Class Level Variables

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

···

--
Posted via http://www.ruby-forum.com/.

<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

···

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

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.

···

On 4/29/07, Cory <coryw@americanmonkey.com> 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).

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.

···

--
Posted via http://www.ruby-forum.com/\.

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

···

On 4/30/07, Ari Brown <ari@aribrown.com> wrote:

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

--
/***********************************/
    Lets go With the float....
/***********************************/

@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

···

In message <D02D2719-35E5-4A0D-9D47-EEDA619A0739@aribrown.com>, Ari Brown writes:

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

···

On 4/29/07, Ari Brown <ari@aribrown.com> wrote:

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?

Gregory Brown 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.

···

On 4/29/07, Cory <coryw@americanmonkey.com> wrote:

--
Posted via http://www.ruby-forum.com/\.

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.

···

On 4/29/07, Cory Wilkerson <coryw@americanmonkey.com> wrote:

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.

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.

···

On 4/29/07, zswu <wuzongsheng@gmail.com> 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

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

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

···

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

Gregory Brown wrote:

···

On 4/29/07, Cory Wilkerson <coryw@americanmonkey.com> 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.

--
Posted via http://www.ruby-forum.com/\.

Huuuum, you are right.

···

On 4/30/07, Gregory Brown <gregory.t.brown@gmail.com> wrote:

On 4/29/07, zswu <wuzongsheng@gmail.com> 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
>
> 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.

--
/***********************************/
    Lets go With the float....
/***********************************/

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.

···

On 4/29/07, Cory Wilkerson <coryw@americanmonkey.com> 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.

--
Rick DeNatale

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

<snip>

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.

···

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

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

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.

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

···

On 4/29/07, Ari Brown <ari@aribrown.com> wrote:

On Apr 29, 2007, at 9:03 PM, Gregory Brown wrote:
<snip>

> 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?

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

···

On Apr 30, 2007, at 1:52 PM, German Monfort wrote:

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

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.

>
> <snip>
>
> > 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?

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

···

On 4/30/07, Gregory Brown <gregory.t.brown@gmail.com> wrote:

On 4/29/07, Ari Brown <ari@aribrown.com> wrote:
> On Apr 29, 2007, at 9:03 PM, Gregory Brown wrote:

--
You see things; and you say Why?
But I dream things that never were; and I say Why not?
-- George Bernard Shaw

<snip>

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.

···

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