Class Level Variables

C

Cory

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
 
A

Ari Brown

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

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
 
Z

zswu

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
 
G

Gregory Brown

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

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.
 
G

Gregory Brown

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.
 
Z

zswu

Huuuum, you are right.

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.
 
C

Cory Wilkerson

Gregory said:
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.
 
G

Gary Wright

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

2) 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 Wright
 
C

Cory Wilkerson

Cory said:
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.
 
G

Gregory Brown

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.
 
C

Cory Wilkerson

Gregory said:
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.
 
R

Rick DeNatale

+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.
 
A

Ari Brown

On Apr 29, 2007, at 9:03 PM, Gregory Brown 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.
 
G

Gregory Brown

On Apr 29, 2007, at 9:03 PM, Gregory Brown 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.
 
R

Robert Dober

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
 
G

Gregory Brown

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...
 
G

German Monfort

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

class C
@@foo =3D 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 =3D 43 # @@foo shared with C, D, and E
@@bar =3D 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 =3D 45
end

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

Gary Wright
Shouldn't be=20
puts D.new.foo =A0 =A0 =A0 # 42 ?

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

Gary Wright

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.

I was illustrating the fact that C and E don't share the same @@bar
due to
initialization order and the location of the definitions of C.bar and
E.bar.

If you called D.new.foo you would get 43 because @@foo is shared by
C, D, and E
and was updated to reference 43 in the class block that defined E.

If you called D.new.bar you would get 45 because the call to 'bar'
would be
implemented by the definition in C where @@bar refers to C's @@bar.
This is
a good example of how class variables are not relative to self!

Gary Wright
 
A

Ari Brown

On Apr 29, 2007, at 11:21 PM, Gregory Brown 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.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,780
Messages
2,569,611
Members
45,276
Latest member
Sawatmakal

Latest Threads

Top