Forum: Ruby class << my_instance and class variables

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
Raphael B. (Guest)
on 2006-05-10 19:55
(Received via mailing list)
Hi,

When running this code,

class A
  def initialize(i)
    @value = i
  end
end

a = A.new(3)

class << a
  @@v = 5
  def test
    @value>@@v
  end
end

a.test

 I get a warning:
"class variable access from toplevel singleton method"

From my understanding, the test method is added to the class specific
to object a, and other instances of A don't have access to that
method. The class variable @@v is also added to the same object
specific class. But then, what exactly does this warning mean, and how
bad is it?

Thanks

Raph
ts (Guest)
on 2006-05-10 20:05
(Received via mailing list)
>>>>> "R" == Raphael B. <removed_email_address@domain.invalid> writes:

R> method. The class variable @@v is also added to the same object
R> specific class.

 Are you sure ?

moulon% ruby -e 'class << Object.new; @@a = 12 end; p @@a'
-e:1: warning: class variable access from toplevel singleton method
12
moulon%


Guy Decoux
Raphael B. (Guest)
on 2006-05-10 20:49
(Received via mailing list)
On 5/10/06, ts <removed_email_address@domain.invalid> wrote:
> >>>>> "R" == Raphael B. <removed_email_address@domain.invalid> writes:
>
> R> method. The class variable @@v is also added to the same object
> R> specific class.
>
>  Are you sure ?
>
> moulon% ruby -e 'class << Object.new; @@a = 12 end; p @@a'
> -e:1: warning: class variable access from toplevel singleton method
> 12

I was not sure ;-)

In the mean time I read this very interesting article:
http://whytheluckystiff.net/articles/seeingMetacla...

So methods are added to the object specific class (the metaclass as
identified in why's article), but class variables are added to the
class of which the object is an instance. Why the difference?

Further on this, if I defined a second instance and try to call test:
b=A.new(6)
b.test

I get the error that test is a private method:
NoMethodError: private method `test' called for #<A:0xb7cbf5ec @value=6>

so it seems it was added to A, but marked as private.

Are there any good reading about this?
Oh, and about my initial question: how bad is the warning I get?

Raph
ts (Guest)
on 2006-05-10 21:07
(Received via mailing list)
>>>>> "R" == Raphael B. <removed_email_address@domain.invalid> writes:

R> So methods are added to the object specific class (the metaclass as
R> identified in why's article), but class variables are added to the
R> class of which the object is an instance.

 Well, no. class variables (i.e @@) are added in the class which is
 cuurently in scope.

R> Further on this, if I defined a second instance and try to call test:
R> b=A.new(6)
R> b.test

 When you do this, ruby find the method Kernel#test which is a private
 method. This is why it give a warning.

R> so it seems it was added to A, but marked as private.

 No, it was added to the singleton class of `a', you have just chosen a
bad
 name for your method (test) :-)

R> Oh, and about my initial question: how bad is the warning I get?

 ruby is trying to say that the variable @@v will be defined in Object,
 because there is no other class where it can define it.


Guy Decoux
Raphael B. (Guest)
on 2006-05-10 21:26
(Received via mailing list)
thanks Guy for your explanations!

>  ruby is trying to say that the variable @@v will be defined in Object,
>  because there is no other class where it can define it.
>

I didn't (and still can't ;-) translate the message  "class variable
access from toplevel singleton method" to your explanation of it.

Anyway, I started to play with class instance variables, and got this
code working, if anyone's interested:

class A
  def initialize(i)
    @value = i
  end

  def test_in_class
    @value>@@v
  end
end

a = A.new(3)

class << a
  @cvalue = 5
  class << self
    attr_reader :cvalue
  end
  def test
    @value>(class << self; self; end).cvalue
  end
end

a.test


Cheers

Raph
This topic is locked and can not be replied to.