class_eval(aString) vs class_eval(aBlock)

Hi,

why does class_eval behave differently is you pass a string or a block to it?
This simple test

class A
  def test_str; p self.class.class_eval("@@v"); end
  def test_blk; p self.class.class_eval { @@v }; end
end

class B < A
  def initialize; @@v = "v.B"; end
end

B.new.test_str
B.new.test_blk

gives this (unexpected?) result

···

$ ruby ./cv2.rb
"v.B"
./cv2.rb:3:in `test_blk': uninitialized class variable @@v in A (NameError)
        from ./cv2.rb:3:in `class_eval'
        from ./cv2.rb:3:in `class_eval'
        from ./cv2.rb:3:in `test_blk'
        from ./cv2.rb:11

--
Gioele <dev@gioelebarabucci.com>

Hi,

why does class_eval behave differently is you pass a string or a block to it?
This simple test

> class A
> def test_str; p self.class.class_eval("@@v"); end
> def test_blk; p self.class.class_eval { @@v }; end
> end
>
> class B < A
> def initialize; @@v = "v.B"; end
> end
>
> B.new.test_str
> B.new.test_blk

gives this (unexpected?) result

> $ ruby ./cv2.rb
> "v.B"
> ./cv2.rb:3:in `test_blk': uninitialized class variable @@v in A (NameError)
> from ./cv2.rb:3:in `class_eval'
> from ./cv2.rb:3:in `class_eval'
> from ./cv2.rb:3:in `test_blk'
> from ./cv2.rb:11

Reason for that is that all blocks are closures (they 'enclose' the
scope they were defined in). In this case, @@v is bound to the @@v
in class A at the time you create the block.

Gioele <dev@gioelebarabucci.com>

E

···

On 2006.01.24 21:19, Gioele Barabucci wrote: