私は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メソッド内で割り当てが失敗する理由を説明できますか?