1

我可以获取一段代码,instance_exec然后得到正确的结果。我想从另一个对象中取出一个方法,并在我的范围内调用其中一个方法。当我从不同的对象中获取一个方法时,将它变成一个过程,然后instance_exec它,我没有得到预期的结果。代码如下。

class Test1
    def ohai(arg)
        "magic is #{@magic} and arg is #{arg}"
    end
end

class Test2
    def initialize
        @magic = "MAGICAL!"
    end

    def scope_checking
        @magic
    end

    def do_it
        ohai = Test1.new.method(:ohai)
        self.instance_exec("foobar", &ohai)
    end
end

describe "Test2 and scopes" do
    before do
        @t2 = Test2.new
    end

    it "has MAGICAL! in @magic" do
        @t2.scope_checking.should == "MAGICAL!"
    end

    # This one fails :(
    it "works like I expect converting a method to a proc" do
        val = @t2.do_it
        val.should == "magic is MAGICAL! and arg is foobar"
    end

    it "should work like I expect" do
        val = @t2.instance_exec do
            "#{@magic}"
        end

        val.should == "MAGICAL!"
    end
end
4

2 回答 2

1

似乎,在 Ruby 中,使用定义的方法def some_method永久绑定到定义它们的类。

因此,当您调用.to_proc它们时,它们会保留其原始实现的绑定,并且您无法重新绑定它们。好吧,您可以,但仅限于与第一个对象相同类型的对象。有可能我可以对继承做一些花哨的事情,但我不这么认为。

解决方案变成而不是使用方法,我只是将实际Proc的 s 放入变量中然后使用它们,因为它们直到执行时才被绑定。

于 2013-04-26T18:45:57.260 回答
0

不确定这是一个多么好的想法,但这通过了您的测试:

class Test1
  def ohai(arg, binding)
    eval('"magic is #{@magic} "', binding).to_s + "and arg is #{arg}"
  end
end

class Test2
  def initialize
    @magic = "MAGICAL!"
  end

  def scope_checking
    @magic
  end

  def get_binding
    return binding()
  end

  def do_it
    self.instance_exec(get_binding) {|binding| Test1.new.ohai("foobar", binding) }
  end
end
于 2013-04-25T17:44:56.563 回答