【问题标题】:instance_eval doesn't work as expectedinstance_eval 没有按预期工作
【发布时间】:2014-08-25 15:26:38
【问题描述】:

我正在尝试使用 Russ Olsen 在他的书 Eloquent Ruby 中公开的方法构建一个小巧的 DSL。但是它对我不起作用。让我们考虑以下代码:

class SayHello
  def initialize
    @message = "Hello."
    instance_eval(yield) if yield
  end

  def say_it
    puts @message
  end
end

SayHello.new { say_it }

我得到的错误是:

say_hello.rb:12:in `block in <main>': undefined local variable or method `say_it' for main:Object (NameError)
    from say_hello.rb:4:in `initialize'
    from say_hello.rb:12:in `new'
    from say_hello.rb:12:in `<main>'

但是……当你使用instance_eval方法时,self的值不应该分配给调用该方法的对象吗?

提前致谢!

【问题讨论】:

    标签: ruby


    【解决方案1】:

    当块运行时,您希望 self 等于您的 SayHello 实例而不是 main 对象。

    我在 Google 上搜索了“ruby change self for a block”,发现 a good answer 这让我认为您应该将代码更改为:

    class SayHello
      def initialize(&p)
        @message = "Hello."
        instance_eval(&p) if block_given?
      end
    
      def say_it
        puts @message
      end
    end
    
    SayHello.new { say_it }
    

    【讨论】:

    • &amp;pyield有什么区别?
    • &amp;p 将方法的块捕获为 proc,然后您可以将其传递给 instance_eval 以更改其 selfyield 只是传递控制块,只有在块完成后才返回它。
    • 是的yield运行块并返回它的值,&amp;p基本上就是块。
    猜你喜欢
    • 2021-10-19
    • 2020-03-18
    • 2012-06-14
    • 2014-11-15
    • 1970-01-01
    • 2012-07-02
    • 2011-09-07
    • 2013-03-03
    • 2015-05-18
    相关资源
    最近更新 更多