【问题标题】:Instance_eval does not work with do/end block, only with {}-blocks [duplicate]Instance_eval 不适用于 do/end 块,仅适用于 {}-blocks [重复]
【发布时间】:2014-01-29 08:10:30
【问题描述】:

如果我有课:

class KlassWithSecret
  def initialize
    @secret = 99
  end
end

然后运行:

puts KlassWithSecret.new.instance_eval { @secret }

它打印 99,但如果我运行:

puts KlassWithSecret.new.instance_eval do
  @secret
end

返回错误:`instance_eval': wrong number of arguments (0 for 1..3) (ArgumentError)

为什么我不能在 instance_eval 中使用 do/end 块?

附:我正在使用 Ruby 2.1.0。

【问题讨论】:

标签: ruby instance-eval


【解决方案1】:

将提供给puts 的表达式括在括号中,因为do..end 块的优先级较低。

puts( KlassWithSecret.new.instance_eval do
  @secret
end )

或使用块的大括号语法

puts KlassWithSecret.new.instance_eval {
  @secret
}

【讨论】:

    【解决方案2】:

    这是因为当你传递带有花括号的块时,它被传递给instance_eval 方法。但是如果你用do-end 传递它,它就会传递给puts 方法,所以instance_eval 不会被阻塞并引发错误。

    【讨论】:

      【解决方案3】:

      这是因为当您使用 do..end 块时,该块被传递给 puts 函数。如果你这样写,带有 do..end 块的代码将起作用

      puts(KlassWithSecret.new.instance_eval do
        @secret
      end)
      

      【讨论】:

        【解决方案4】:
        a = Proc.new {@secret}
        puts KlassWithSecret.new.instance_eval(&a)
        # 99
        

        它说puts KlaccWithSecret do @secret end 没有获得Proc(block)。

        【讨论】:

          【解决方案5】:

          Ruby(2.0.0) 有效。 代码:

          KlassWithSecret.new.instance_eval do
            p @secret
          end
          # 99
          

          没问题。

          【讨论】:

          • 它有效,因为您错过了对puts 的调用。
          • 我深思熟虑。我发布了一个新答案。希望对你有帮助。
          • @toro2k 我认为这是一个代码高尔夫...... :)
          猜你喜欢
          • 1970-01-01
          • 2012-04-09
          • 1970-01-01
          • 2016-10-08
          • 2016-05-20
          • 2016-03-26
          • 2018-04-12
          • 2017-09-13
          • 1970-01-01
          相关资源
          最近更新 更多