Class Level Variables


#1

Alright, I’m missing some core ruby concept here that I just can’t
figure out; any assistance would be excellent and welcome:

Long story short, I’m attempting to modify class level variables @@foo,
@@bar from an action in a ruby controller (an instance of a given
controller).

It seems that the class level variables set just fine…however, the
next time the action is invoked, they’re nil again.

Code here: http://rafb.net/p/U3Q9VC20.html


#2

On Apr 29, 2007, at 8:04 PM, Cory wrote:

newbie question pertaining to class level variables:

What’s the difference between @foo and @@foo? Is there even a
difference?

---------------------------------------------------------------|
~Ari
“I don’t suffer from insanity. I enjoy every minute of it” --1337est
man alive


#3

If you know C++.

@foo seams look link a normal member variable , i.e. private TYPE foo
@@foo seams look link a static member variable, i.e. static TYPE foo

Initialize the class variable in the constroctor is a good idea.
That’s will make the class variable valide all of the class.
class xxx
def initialize
@@foo = XXXXX
end
end


#4

In message removed_email_address@domain.invalid, Ari
Brown writes:

newbie question pertaining to class level variables:

What’s the difference between @foo and @@foo? Is there even a
difference?

@foo = instance variable; each instance has one
@@foo = class variable; only one shared among all class members

class Example
def print
puts @y, @@z
end
def initialize(x)
@y = x
@@z = x
end
end
e1 = Example.new(1)
e2 = Example.new(2)
e1.print
e2.print

The first print prints 1 and 2, the second prints 2 and 2. The first
new sets e1.y to 1, and Example.z to 1. The second sets e2.y to 2,
and Example.z to 2. There’s only one @@z (also called “Example.z”), but
there’s one @y for each instance.

-s


#5

On 4/29/07, Ari B. removed_email_address@domain.invalid wrote:

On Apr 29, 2007, at 8:04 PM, Cory wrote:

newbie question pertaining to class level variables:

What’s the difference between @foo and @@foo? Is there even a
difference?

I wrote a newbie oriented post on this a while ago.
Hope it helps…

http://www.oreillynet.com/ruby/blog/2007/01/nubygems_dont_use_class_variab_1.html


#6

On 4/29/07, Cory removed_email_address@domain.invalid wrote:

Alright, I’m missing some core ruby concept here that I just can’t
figure out; any assistance would be excellent and welcome:

Long story short, I’m attempting to modify class level variables @@foo,
@@bar from an action in a ruby controller (an instance of a given
controller).

There is no such thing as a Ruby controller. I think you may actually
be asking a question about Ruby on Rails, so please use the rails
mailing list.

warm regards,
-gregory.


#7

On 4/29/07, zswu removed_email_address@domain.invalid wrote:

end

end

Please don’t do this. That assignment would happen every time you
create an instance of the object, which completely defeats the purpose
of class level variables. (Whether you use class instance variables or
class variables).

Class level variables are shared by all your instances.


#8

Gregory B. wrote:

On 4/29/07, Cory removed_email_address@domain.invalid wrote:

Alright, I’m missing some core ruby concept here that I just can’t
figure out; any assistance would be excellent and welcome:

Long story short, I’m attempting to modify class level variables @@foo,
@@bar from an action in a ruby controller (an instance of a given
controller).

There is no such thing as a Ruby controller. I think you may actually
be asking a question about Ruby on Rails, so please use the rails
mailing list.

warm regards,
-gregory.

You’re right - it’s a rails controller; but it’s a ruby question.
Apparently my question has now been hijacked and we’re now discussing
the difference between class level variables and instance level
variables.

Every test I’ve cooked out simply won’t allow me to maintain state in a
class level variable set from an instance level context. That’s the
core of the question.


#9

Huuuum, you are right.


#10

On Apr 29, 2007, at 8:44 PM, zswu wrote:

If you know C++.

@foo seams look link a normal member variable , i.e. private TYPE foo
@@foo seams look link a static member variable, i.e. static TYPE foo

I think a lot of confusion about Ruby class variables comes from
trying to compare them to similarly named constructs in other languages.

There is also a tendency to think class variables are like instance
variables because @@ is like @. Again, you’ll be mislead by that
assumption.

  1. Class variables are lexically scoped. They are not associated
    with the object identified by ‘self’ but instead by the innermost
    class block:

class B;end
class A
@@foo = 42 # @@foo for A
def foo
@@foo # @@foo for A
end
def B.foo
@@foo # self is B but @@foo is for A
end
end

puts A.new.foo # 42
puts B.foo # 42

This lexical scoping is really important to understand when you
start using singleton class blocks, class_eval, module_eval,
or define_method, since the these constructs don’t introduce a lexical
scope:

class X
@@foo = 42
class Y
@@foo = 43
X.class_eval {
puts @@foo # 43, this is Y’s @@foo, not X’s @@foo
}
end
end

  1. Class variables are associated with a class and its subclasses
    and the order of initialization is important.

class C
@@foo = 42 # shared by C and its decendents!
def foo
@@foo # shared with C, D, and E
end
def bar
@@bar # this is C’s @@bar
end
end

class D < C
end

class E < C
@@foo = 43 # @@foo shared with C, D, and E
@@bar = 44 # @@bar only defined for E
def bar
@@bar # this is E’s @@bar
end
end

puts D.new.foo # 43

puts E.new.bar # 44
puts C.new.bar # undefined!

class C
@@bar = 45
end

puts C.new.bar # 45
puts E.new.bar # still 44

Initialize the class variable in the constroctor is a good idea.
That’s will make the class variable valide all of the class.
class xxx
def initialize
@@foo = XXXXX
end
end

This is a really bad idea. Every time you create a new instance,
you’ll reset the class variable.

Gary W.


#11

On 4/29/07, Cory W. removed_email_address@domain.invalid wrote:

Code here: http://rafb.net/p/U3Q9VC20.html

It just struck me - it likely is a rails issue, I’m running in
development mode and methinks it’s likely reloading the class every
single time.

And - sorry if I seemed snippy, been fighting this for a while.

As far as I know, it’s a rails issue period. Unless you’re storing
something in the database(either via sessions or models), you don’t
have state preservation. I don’t know enough about Rails to give you
the information you need about that, others on this list do.

However, the best place to ask this is certainly the Rails list.


#12

Gregory B. wrote:

On 4/29/07, Cory W. removed_email_address@domain.invalid wrote:

Code here: http://rafb.net/p/U3Q9VC20.html

It just struck me - it likely is a rails issue, I’m running in
development mode and methinks it’s likely reloading the class every
single time.

And - sorry if I seemed snippy, been fighting this for a while.

As far as I know, it’s a rails issue period. Unless you’re storing
something in the database(either via sessions or models), you don’t
have state preservation. I don’t know enough about Rails to give you
the information you need about that, others on this list do.

However, the best place to ask this is certainly the Rails list.

+1 for Greg. It was an environment issue - meaning, when you’re running
rails in development mode; you get continual class reloading; thusly -
no ‘state’ at the class level.

I’ll head there next time. Thanks for listening folks.


#13

Cory wrote:

Alright, I’m missing some core ruby concept here that I just can’t
figure out; any assistance would be excellent and welcome:

Long story short, I’m attempting to modify class level variables @@foo,
@@bar from an action in a ruby controller (an instance of a given
controller).

It seems that the class level variables set just fine…however, the
next time the action is invoked, they’re nil again.

Code here: http://rafb.net/p/U3Q9VC20.html

It just struck me - it likely is a rails issue, I’m running in
development mode and methinks it’s likely reloading the class every
single time.

And - sorry if I seemed snippy, been fighting this for a while.


#14

On Apr 29, 2007, at 9:03 PM, Gregory B. wrote:

Please don’t do this. That assignment would happen every time you
create an instance of the object, which completely defeats the purpose
of class level variables. (Whether you use class instance variables or
class variables).

So use @@foo for general ideas (like @@foo = {} and when used in some
file.open(path, ‘r’) do … command) and @foo for variables that
hold specific values?

Got it.

P.S. = Is there some site that has a bunch of secrets that everyone
(but me) knows in making your Ruby code look like Ruby?

~ Ari
English is like a pseudo-random number generator - there are a
bajillion rules to it, but nobody cares.


#15

On 4/29/07, Ari B. removed_email_address@domain.invalid wrote:

file.open(path, ‘r’) do … command) and @foo for variables that
hold specific values?

Don’t use @@foo, ever. Unless you know why you want to. They add
unnecessary confusion. Instead, use class instance variables.


#16

On 4/29/07, Cory W. removed_email_address@domain.invalid wrote:

+1 for Greg. It was an environment issue - meaning, when you’re running
rails in development mode; you get continual class reloading; thusly -
no ‘state’ at the class level.

And don’t count on persistence in the production environment either.
For one thing, it’s likely that the deployment will eventually end up
using something like mongrel_cluster, so each instance of the runtime
will have it’s own state, except for that shared through external
means such as the database.


Rick DeNatale

My blog on Ruby
http://talklikeaduck.denhaven2.com/


#17

On 4/30/07, Gregory B. removed_email_address@domain.invalid wrote:

So use @@foo for general ideas (like @@foo = {} and when used in some
file.open(path, ‘r’) do … command) and @foo for variables that
hold specific values?

Don’t use @@foo, ever. Unless you know why you want to. They add
unnecessary confusion. Instead, use class instance variables.

Could not agree more with you, however, I would not dare stating this
as a General Rule of Conduct.
Will @@class_iv go away? I do not think so.

Cheers
Robert


#18

end
end

puts C.new.bar # 45
puts E.new.bar # still 44

Gary W.
Shouldn’t be
puts D.new.foo # 42 ?

Because D < C and has no foo method defined (so it uses C’ foo) and also
has
no @@foo defined (so it uses C’s @@foo) which is set to 42 not 43.
I’m confused here.


#19

On 4/30/07, Robert D. removed_email_address@domain.invalid wrote:

On 4/30/07, Gregory B. removed_email_address@domain.invalid wrote:

Don’t use @@foo, ever. Unless you know why you want to. They add

emp added

Could not agree more with you, however, I would not dare stating this
as a General Rule of Conduct.
Will @@class_iv go away? I do not think so.

I agree with you that it can’t be just a rule. Ruby 1.9 fixes some
issues with them though, so it’ll be less scary there…

I’m still waiting for the killer use case that justifies them…


#20

On Apr 29, 2007, at 11:21 PM, Gregory B. wrote:

Don’t use @@foo, ever. Unless you know why you want to. They add
unnecessary confusion. Instead, use class instance variables.

Sounds like a good rule to me

--------------------------------------------|
If you’re not living on the edge,
then you’re just wasting space.