web-dev-qa-db-ja.com

RubyでDSLを書くためのチュートリアル

RubyにDSLを実装する方法に関する優れたオンラインチュートリアルは何ですか?プロセス全体を説明する実践的な例を探しています。

DSLとRubyに関する良い本にこの質問があることを知っています: RubyベースのDSLの良い本

32
Stephan

これは、RubyでのDSLの構築に関する一連のすばらしい記事だと思います。

http://jroller.com/rolsen/entry/building_a_dsl_in_Ruby

35
Upgradingdave

Docilegem を使用すると、gemを使用するか、または ソースコード を読み取ることで、これを非常に簡単に理解できます。動作します。

DSL経由でピザを作りたいとしましょう

Pizza = Struct.new(:cheese, :pepperoni, :bacon, :sauce)

そして、あなたはピザを作るためにビルダーパターンを使います

class PizzaBuilder
  def cheese(v=true); @cheese = v; end
  def pepperoni(v=true); @pepperoni = v; end
  def bacon(v=true); @bacon = v; end
  def sauce(v=nil); @sauce = v; end
  def build
    Pizza.new(!!@cheese, !!@pepperoni, !!@bacon, @sauce)
  end
end

そして、あなたは[〜#〜] dsl [〜#〜]を望み、次のように言います

@sauce = :extra
pizza do
  bacon
  cheese
  sauce @sauce
end
# => should return Pizza.new(true, false, true, :extra)

pizzaメソッドを次のように定義するだけです。

require 'docile'

def pizza(&block)
  Docile.dsl_eval(PizzaBuilder.new, &block).build
end

これで完了です。

34
ms-tg

yieldinstance_evalを使用する2つの非常に重要なパターンを明示的にカバーしているので、このチュートリアルは非常に優れています。

yieldとinstance_evalを使用してDSLを構築するにはどうすればよいですか?

4
Alex Popov

DSLを作成するための前提条件は、ブロックの生成、Rubyのメソッド検索プロセス、method_missing()などの高度なプログラミング手法を理解することです。 メタプログラミングRuby を読むことは、これらの高度なRubyスキル(この本には、内部DSLの記述に関するセクションも含まれています)。

約20行のコードで Ruby DSLでHTMLマークアップを生成するDSL)の作成方法に関するブログ投稿 を書きました。いくつかの小さなおもちゃの例から始めるのがはるかに良いです。 Erector のようなプロダクショングレードのアプリケーションにすぐにジャンプするよりも、ms-tgによって提案された Docile gem のソースコードを調べることは優れていますが、それでも最初のDSLとしては少し圧倒的です。高度なRubyプログラミング手法をいくつか学び、おもちゃの例をいくつか作成してから、Docileソースコードを調べます。

@ ms-tgで説明されているDocile gemの機能の一部を最初から取得する方法は次のとおりです。

_def dsl(obj, &block)
  obj.instance_eval(&block)
end

Pizza = Struct.new(:cheese, :pepperoni, :bacon, :sauce)
obj = Pizza.new

dsl(obj) do |pizza|
  pizza.cheese = true
  pizza.pepperoni = true
  pizza.sauce = :extra
end

p obj
# => #<struct Pizza cheese=true, pepperoni=true, bacon=nil, sauce=:extra>
_

dsl()メソッドは、配列を作成する Docile README の例のような、より簡単な例にも使用できます。

_arr = []

dsl(arr) do
  Push(1)
  Push(2)
  pop
  Push(3)
end

p arr
_
1
Powers