0

次のような小さな DSL があります。

ActivityLogger.log do
  activity('27-06-2012') do
    eat do |act|
     act.duration = 15
     act.priority = 5
    end
  end
end

最も内側のブロックのブロック パラメータを失うようにリファクタリングしたいので、次のようになります。

ActivityLogger.log do
  activity('27-06-2012') do
    eat do
     duration = 15
     priority = 5
    end
  end
end

この#eatメソッドは、Log オブジェクトをインスタンス化します。

def eat(&block)
  @logs << Log.new(Eat, &block)
end

ログのコンストラクターselfは最後の行で生成されます。

def initialize(activity, &block)
  @activity = activity
  yield self
end

私の考えでは、そこが問題です。instance_evalメソッドでの使用#eat(以下のリンク#2を参照)とログのコンストラクターからのステートメントの完全な削除(リンク#3)の両方を試しましyieldたが、これらのアプローチはどれも機能しません(ログオブジェクトは作成されますが、取得されません#durationおよび#priorityメソッド セット)。

リンクは次のとおりです。

1)ブロックパラメータを持つ実用的な DSL

2)機能しない DSL、最初のリファクタリングの試み

3)機能しない DSL、2 回目のリファクタリングの試み

ありがとう!

4

1 に答える 1

4

duration = 15期待どおりにsetterメソッドを呼び出さないが、ローカル変数を定義するduration。を介してセッターを明示的に呼び出すか、次のようにセッターをself.duration = 15実装する必要があります。

def duration(value)
  @duration = value
end

と呼び出しますduration 15

于 2012-06-28T12:09:32.753 に答える