This question already has an answer here:
-
Ruby block and unparenthesized arguments
1 answer
-
Ruby Block Syntax Error [duplicate]
1 answer
If I have a class:
class KlassWithSecret
def initialize
@secret = 99
end
end
and run:
puts KlassWithSecret.new.instance_eval { @secret }
it prints 99, but if I run:
puts KlassWithSecret.new.instance_eval do
@secret
end
It returns an error: `instance_eval': wrong number of arguments (0 for 1..3) (ArgumentError)
Why can't I use do/end blocks with instance_eval
?
P.S. I am using Ruby 2.1.0.
It's because when you pass block with curly braces, it is passed to instance_eval
method. But if you pass it with do-end
, it's passed to puts
method, so instance_eval
doesn't get block and raises an error.
Enclose expression supplied to puts
in parenthesis because lower precedence of do..end
block.
puts( KlassWithSecret.new.instance_eval do
@secret
end )
or use brace syntax of block
puts KlassWithSecret.new.instance_eval {
@secret
}
This is because when you use do..end block, the block is passed to the puts function. The code with do..end block will work if you write it like this
puts(KlassWithSecret.new.instance_eval do
@secret
end)
a = Proc.new {@secret}
puts KlassWithSecret.new.instance_eval(&a)
# 99
It say that puts KlaccWithSecret do @secret end
does not gain the Proc
(block).
Ruby(2.0.0) works.
Code:
KlassWithSecret.new.instance_eval do
p @secret
end
# 99
no problem.