2014-01-10 22 views
3

如果我有一个类:instance_eval的不DO /结束块工作,只能用{} -blocks

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。

+1

这里工作(红宝石2.0.0)你使用的是什么红宝石版本? – levinalex

+0

适合我(2.1.0)。你确定你粘贴的代码导致错误? –

+0

无法在1.9.3中重现。如果你有一些较老的/不同的Ruby实现,它可能与'do..end'块的优先级较低,然后是'{..}'块有关。 –

回答

4

这是因为当你通过块带花括号的,它被传递给instance_eval方法。但是,如果您将其传递给do-end,它将传递给puts方法,因此instance_eval不会获得块并引发错误。

5

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

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

或使用块的大括号语法

puts KlassWithSecret.new.instance_eval { 
    @secret 
} 
3

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

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

Ruby(2.0.0)的工作原理。 代码:

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

没问题。

+1

它的工作原理是因为你错过了对'puts'的调用。 – toro2k

+0

我深思。我发布了一个新的答案。希望能帮助你。 –

+0

@ toro2k我认为这是一个代码高尔夫球...... :) –

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

这就是说puts KlaccWithSecret do @secret end没有获得Proc(块)。