T
Thomas Gantner
Hi
I stumbled upon a problem with 'instance_eval' (using ruby 1.8.5 on
linux-x86_64). Simplified code example:
irb:01> S = Struct.new
a)
=> S
irb:02> s = S.new(1)
=> #<struct S a=1>
irb:03> s.a
=> 1
irb:04> s.a = 2
=> 2
irb:05> s
=> #<struct S a=2>
irb:06> s.instance_eval { puts a }
2
=> nil
irb:07> s.instance_eval { a = 3 }
=> 3
irb:08> s
=> #<struct S a=2>
irb:09> s.instance_eval { self.a = 3 }
=> 3
irb:10> s
=> #<struct S a=3>
My problem is in line 07: it seems that the 'a' in the block is treated as a
local variable, therefore all the writer-accessor methods ('a=') are hidden
within the block. I get the same result when instance_eval-ing the
string "a = 3" instead of the block variant.
Is there a way to avoid this behaviour without using 'self.a' or passing the
struct as a parameter into the block (which quite obsoletes the meaning of
instance_eval)?
My real world use of this pattern is using a block with 'initialize()':
class C
def initialize(&blk)
@format = Struct.new( ... many, many elements with default values ...)
@format.instance_eval(&blk)
end
end
To explicitly override some default format-values I want to use
c = C.new { elem8 = 8; elem17 = 'test'; ... }
This won't work as explained above. I know I can use
c = C.new {|format| format.elem8 = 8; format.elem17 = 'test'; ... }
or
c = C.new { self.elem8 = 8; self.elem17 = 'test'; ... }
but both seem somewhat redundant and need too much typing (yeah I know I'm
lazy ;-).
Thanks for any suggestions.
-Thomas
I stumbled upon a problem with 'instance_eval' (using ruby 1.8.5 on
linux-x86_64). Simplified code example:
irb:01> S = Struct.new
=> S
irb:02> s = S.new(1)
=> #<struct S a=1>
irb:03> s.a
=> 1
irb:04> s.a = 2
=> 2
irb:05> s
=> #<struct S a=2>
irb:06> s.instance_eval { puts a }
2
=> nil
irb:07> s.instance_eval { a = 3 }
=> 3
irb:08> s
=> #<struct S a=2>
irb:09> s.instance_eval { self.a = 3 }
=> 3
irb:10> s
=> #<struct S a=3>
My problem is in line 07: it seems that the 'a' in the block is treated as a
local variable, therefore all the writer-accessor methods ('a=') are hidden
within the block. I get the same result when instance_eval-ing the
string "a = 3" instead of the block variant.
Is there a way to avoid this behaviour without using 'self.a' or passing the
struct as a parameter into the block (which quite obsoletes the meaning of
instance_eval)?
My real world use of this pattern is using a block with 'initialize()':
class C
def initialize(&blk)
@format = Struct.new( ... many, many elements with default values ...)
@format.instance_eval(&blk)
end
end
To explicitly override some default format-values I want to use
c = C.new { elem8 = 8; elem17 = 'test'; ... }
This won't work as explained above. I know I can use
c = C.new {|format| format.elem8 = 8; format.elem17 = 'test'; ... }
or
c = C.new { self.elem8 = 8; self.elem17 = 'test'; ... }
but both seem somewhat redundant and need too much typing (yeah I know I'm
lazy ;-).
Thanks for any suggestions.
-Thomas