Newbie question: About class variable and class_eval

Hi all,
Please look at the following code

···

-----------------------------------------------------------
class Cls
  @@cv = 0
  def initialize
    @iv = 1
  end
end

c=Cls.new
Cls.class_eval { def iv() @iv end }
puts c.iv
Cls.class_eval { def cv() @@cv end }
puts c.cv
-------------------------------------------------------------
When running this code snippet, I got the result:
$ ruby classvar.rb
1
classvar.rb:11:in `cv': uninitialized class variable @@cv in Object
(NameError).

Why I can't get the class variable in class_eval?

Class variables (i.e. starting with @@) have wierd scoping.
The @@cv you refer to in your closure is looking for resolution
in the scope of the class in which the closure is defined, in this case
the top level Object class.

The only way I know of to get the effect you want is to use string eval:

  Cls.class_eval "def cv() @@cv end "

Regards,

Sean

···

On 11/10/05, mzhang.cn@gmail.com <mzhang.cn@gmail.com> wrote:

Hi all,
Please look at the following code
-----------------------------------------------------------
class Cls
@@cv = 0
def initialize
   @iv = 1
end
end

c=Cls.new
Cls.class_eval { def iv() @iv end }
puts c.iv
Cls.class_eval { def cv() @@cv end }
puts c.cv
-------------------------------------------------------------
When running this code snippet, I got the result:
$ ruby classvar.rb
1
classvar.rb:11:in `cv': uninitialized class variable @@cv in Object
(NameError).

Why I can't get the class variable in class_eval?

mzhang.cn@gmail.com a écrit :

Hi all,
Please look at the following code
-----------------------------------------------------------
class Cls
  @@cv = 0
  def initialize
    @iv = 1
  end
end

c=Cls.new
Cls.class_eval { def iv() @iv end }
puts c.iv
Cls.class_eval { def cv() @@cv end }
puts c.cv
-------------------------------------------------------------
When running this code snippet, I got the result:
$ ruby classvar.rb
1
classvar.rb:11:in `cv': uninitialized class variable @@cv in Object
(NameError).

Why I can't get the class variable in class_eval?

You may just avoid class variable @@cv and use class instance variable
instead:

---8<---8<---8<---8<---8<---8<---8<---8<---8<---8<---8<---8<
class Cls
  @cv = 0
  def initialize
    @iv = 1
  end
end

c=Cls.new
Cls.class_eval { def iv() @iv end }
puts c.iv
Cls.class_eval { class <<self; def cv() @cv end; end }
puts Cls.cv
Cls.class_eval { def cv() self.class.cv end }
puts c.cv
---8<---8<---8<---8<---8<---8<---8<---8<---8<---8<---8<---8<

It works because classes in ruby are objects themselves.

···

--
Lionel Thiry

Personal web site: http://users.skynet.be/lthiry/

Hi --

···

On Fri, 11 Nov 2005, Lionel Thiry wrote:

---8<---8<---8<---8<---8<---8<---8<---8<---8<---8<---8<---8<
class Cls
@cv = 0
def initialize
   @iv = 1
end
end

c=Cls.new
Cls.class_eval { def iv() @iv end }
puts c.iv
Cls.class_eval { class <<self; def cv() @cv end; end }

You can get at that more directly:

   def Cls.cv; @cv; end

(unless you need something from the surrounding scope, of course).

David

--
David A. Black
dblack@wobblini.net