1

私はDSLを作ることを実験していて、私を混乱させる何かに出くわしました。私のcallメソッドでは、ブロックを評価する前に@mymethodの初期値を設定したいと思いました。変数に直接割り当てると機能します。

class Test

  class << self
    attr_accessor :mymethod
  end

  def self.call(&block)
    @mymethod="foo"
    class_eval &block
  end

end

Test.call do
  puts "mymethod returned: #{mymethod}"
  mymethod = "bar"
  puts "mymethod is now: #{mymethod}"
end

どちらが返されますか:

[1] pry(main)> load 'test.rb'
mymethod returned: foo
mymethod is now: bar
=> true

しかし、これはうまくいくはずで、うまくいかないように感じます。唯一変更されたのは、@がmymethodへの割り当てから削除されたため、attr_accessorによって作成されたmymethod=メソッドを使用する必要があると思います。

class Test

  class << self
    attr_accessor :mymethod
  end

  def self.call(&block)
    mymethod="foo"
    class_eval &block
  end

end

Test.call do
  puts "mymethod returned: #{mymethod}"
  mymethod = "bar"
  puts "mymethod is now: #{mymethod}"
end

ただし、呼び出し内からのmymethodへの割り当ては失敗しますが、ブロック内の同じ割り当ては成功します。

[1] pry(main)> load 'test.rb'
mymethod returned: 
mymethod is now: bar
=> true

何が起きてる?誰かがcallメソッド内で割り当てが失敗する理由を説明できますか?

4

1 に答える 1

2

あなたの場合、メソッド を呼び出すのではなく、ローカル変数mymethod="foo"を定義します。mymethod
mymethod=

self.mymethod="foo"代わりに使用してください

于 2012-12-01T03:16:34.350 に答える