Instance_eval不适用于do / end块,仅适用于{} -blocks

时间:2014-01-10 11:13:07

标签: ruby instance-eval

如果我有课:

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块?

P.S。我使用的是Ruby 2.1.0。

5 个答案:

答案 0 :(得分:5)

将括号内的puts附加表达式括起来,因为do..end阻止优先级较低。

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

或使用块

的大括号语法
puts KlassWithSecret.new.instance_eval {
  @secret
}

答案 1 :(得分:4)

这是因为当您使用花括号传递块时,它会传递给instance_eval方法。但是,如果您使用do-end传递它,则会将其传递给puts方法,因此instance_eval不会阻止并引发错误。

答案 2 :(得分:3)

这是因为当你使用do..end块时,块被传递给puts函数。如果您像这样编写

,那么带有do..end块的代码将起作用
puts(KlassWithSecret.new.instance_eval do
  @secret
end)

答案 3 :(得分:0)

a = Proc.new {@secret}
puts KlassWithSecret.new.instance_eval(&a)
# 99

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

答案 4 :(得分:-1)

Ruby(2.0.0)有效。 代码:

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

没问题。