Ask a Question related to Ruby, Design and Development.
-
Martin Weber #1
Re: Class variables - a surprising result
On Thu, Aug 21, 2003 at 06:33:09PM +0900, Jason Williams wrote:
Class variable allocation is per class scope, not per subclass scope.> class Sup
> @@x = "A"
> def test
> print @@x
> end
> end
>
> class Sub1 < Sup
> @@x = "B"
> end
>
> class Sub2 < Sup
> @@x = "C"
> end
>
> Sup.new.test
> Sub1.new.test
> Sub2.new.test
>
>
> I expect this to print "ABC", and yet it prints "CCC". Why is this?
Sub1, Sub2 and Sup really do share their class variables. Now don't
ask me for the "why exactly"...
-Martin
Martin Weber Guest
-
#25377 [Bgs]: Class variables can be added out of class definition
ID: 25377 Updated by: helly@php.net Reported By: forseti at oak dot rpg dot pl Status: Bogus Bug Type: ... -
#25377 [Opn->Bgs]: Class variables can be added out of class definition
ID: 25377 Updated by: sniper@php.net Reported By: forseti at oak dot rpg dot pl -Status: Open +Status: ... -
Instance- and class-variables (was mixing in class methods)
Hi -- On Thu, 2 Oct 2003, Mark J. Reed wrote: Also, every object should have the right to maintain state in instance variables that are... -
Instance- and class-variables (was mixing in class methods)
Hi -- On Fri, 3 Oct 2003 dblack@superlink.net wrote: And of course the fact that it might actually be self.class.class_eval { @var } also... -
Instance- and class-variables (was mixing in class methods)
Hi -- On Thu, 2 Oct 2003, Gavin Sinclair wrote: Ummm, what array? :-) I think you'd need something like: class Project class << self... -
David Heinemeier Hansson #2
Re: Class variables - a surprising result
> Class variable allocation is per class scope, not per subclass scope.
I was fooled by this as well. I don't know why I intuitively would> Sub1, Sub2 and Sup really do share their class variables. Now don't
> ask me for the "why exactly"...
think that a subclass would get its own scope, but I did. Having your
own scope as a subclass would be a really neat addition, though. But
perhaps a reason from Matz would shed light?
/ David
David Heinemeier Hansson Guest
-
Patrick Zesar #3
Re: Class variables - a surprising result
> class Sup
hwow - for the stupid (me):> @@x = "A"
> def test
> print @@x
> end
> end
>
> class Sub1 < Sup
> @@x = "B"
> end
>
> class Sub2 < Sup
> @@x = "C"
> end
>
> Sup.new.test
> Sub1.new.test
> Sub2.new.test
>
>
> I expect this to print "ABC", and yet it prints "CCC". Why is this?
@@x seems to be the same thing for the whole inheritance-hierarchy (or
whatever this thing is called)... but i thought every class has it's very
own class-vars....
i mean... what's the purpose of that? hmmm. i did never notice this. i guess
it just seems so strange due to me not being familiar with it this way...
and - am i right? - in java it would say ABC, wouldn't it?
strange...
patrick
Patrick Zesar Guest
-
Garance A Drosihn #4
Re: Class variables - a surprising result
At 6:33 PM +0900 8/21/03, Jason Williams wrote:
That's what I would expect to happen, although I am not sure> class Sup
> @@x = "A"
> def test
> print @@x
> end
> end
>
> class Sub1 < Sup
> @@x = "B"
> end
>
> class Sub2 < Sup
> @@x = "C"
> end
>
> Sup.new.test
> Sub1.new.test
> Sub2.new.test
>
>I expect this to print "ABC", and yet it prints "CCC".
>Why is this?
I could give a good explanation as to why it is "obvious"
that it should work that way.
As to what exactly is happening, the assignments to @@x are
not inside any method. The assignments are processed as they
are read in, not in the order that '.new' (or any other method)
is called on any of the classes. Perhaps the following will
give you a better idea of why you ended up with 'CCC':
# - - - - start
class Sup
@@x = "A"
@@line = 0
def Sup.Ctest
@@line += 1
@@x += @@x[0,1]
print @@line, "-", @@x, "\n"
end
end
Sup.Ctest # first test
Sup.Ctest # second test
class Sub1 < Sup # define subclass
@@x = "B"
end
Sub1.Ctest # third test
Sup.Ctest # fourth test
# - - - - end
This produces:
1-AA
2-AAA
3-BB
4-BBB
I am not sure if that really helps you with the question
you're asking, though. Note that since you are only using
class variables for this example, we can simply use a class
method. There is no need for creating any instances of
either of these classes, as far as the class variables are
concerned.
To get back to why there would be only one @@x for a class
and all it's subclasses, let me refer to a line from the
"Programming Ruby" (pickaxe) book: "A class variable is
shared among all objects of a class, and is also accessible
to the class methods...".
Any object which is an instance of 'Sub1' is also, by
definition, an instance of 'Sup'. If a class variable is
shared among *all* objects of class 'Sup', then the exact
same variable must also be shared with the objects which
happen to be from class 'Sub1'.
--
Garance Alistair Drosehn = [email]gad@gilead.netel.rpi.edu[/email]
Senior Systems Programmer or [email]gad@freebsd.org[/email]
Rensselaer Polytechnic Institute or [email]drosih@rpi.edu[/email]
Garance A Drosihn Guest
-
Ged Byrne #5
Re: Class variables - a surprising result
class Sup
@@x = "A"
def test
print @@x
end
end
class Sub1 < Sup
@@x = "B"
end
class Sub2 < Sup
@@x = "C"
end
Sup.new.test
Sub1.new.test
Sub2.new.testI think I know whats going on.>>> CCC
When a variable is first used, that is where it is
declared. Unlike Java there is no separate
declaration. If you like, declaration is automatic
when the variable is first reference.
So Sup is declared. Class variable @@x is referenced
and associated with Sup.
Sup1 is declared. @@x is referenced. @@x is not
found in the current class, so super.@@x is
referenced.
@@x is found, and updated.
Note thae @@x = "B" is part of the classes
declaration, and so will always be invoked, and that
the 'message' will be passed back to Sup, thus
updating the value of @@x in Sup.
Same thing happens all over again in Sup2.
Here is the code to get the desired result.
class Sup
@@x = nil
writer: @@x
def initialize
@@x = "A"
end
def test
print @@x
end
end
class Sub1 < Sup
def initialize
@@x = "B"
end
end
class Sub2 < Sup
def initialize
@@x = "C"
end
end
Sup.new.test
Sub1.new.test
Sub2.new.test
However, things still don't work out right if we>>> ABC
assign to variables first. Replace the last three
lines with:
s = Sup.new
s1a = Sub1.new
s1b = Sub1.new
s2a = Sub2.new
s2b = Sub2.new
s.test
s1a.test
s1b.test
s2a.test
s2b.test
Is this suprising? Perhaps not, here is the>> CCC
equivalent Java code:
class sup {
static char x = 'A';
void test() {
System.out.print(x);
}
}
class sup1 extends sup {
{ x = 'B'; }
}
class sup2 extends sup {
{ x = 'C'; }
}
The original scenario cannot be replicated in Java>>> CCC
because a class is loaded and initialised at first
use, rather than at declaration.
class sup {
static char x;
sup() {
x = 'A';
}
void test() {
System.out.print(x);
}
}
class sup1 extends sup {
static char x;
sup1() {
x = 'B';
}
void test() {
System.out.print(x);
}
}
class sup2 extends sup {
static char x;
sup2() {
x = 'C';
}
void test() {
System.out.print(x);
}
}
I can't find any cleaner way to do this in Java.
Remove either the duplicate declaration of x or test()
and your back to the original problem.
So whats the best approach in ruby? To keep a class
hash that contains a value associated with each class?
__________________________________________________ ______________________
Want to chat instantly with your online friends? Get the FREE Yahoo!
Messenger [url]http://uk.messenger.yahoo.com/[/url]
Ged Byrne Guest
-
Gawnsoft #6
Re: Class variables - a surprising result
On Thu, 21 Aug 2003 19:02:43 +0900, David Heinemeier Hansson
<david@loudthinking.com> wrote (more or less):
A class-instance variable is one in which the scope is specific to a>>> Class variable allocation is per class scope, not per subclass scope.
>> Sub1, Sub2 and Sup really do share their class variables. Now don't
>> ask me for the "why exactly"...
>I was fooled by this as well. I don't know why I intuitively would
>think that a subclass would get its own scope, but I did. Having your
>own scope as a subclass would be a really neat addition, though. But
>perhaps a reason from Matz would shed light?
given (sub)class.
Am I correct in dimly recalling that Ruby has support for
class-instance variables?
Cheers,
Euan
Gawnsoft: [url]http://www.gawnsoft.co.sr[/url]
Symbian/Epoc wiki: [url]http://html.dnsalias.net:1122[/url]
Smalltalk links (harvested from comp.lang.smalltalk) [url]http://html.dnsalias.net/gawnsoft/smalltalk[/url]
Gawnsoft Guest
-
Robert Feldt #7
Re: Class variables - a surprising result
Try:
class Sup
@x = "A"
def Sup.x
@x
end
def test
print self.class.x
end
end
class Sub1 < Sup
@x = "B"
end
class Sub2 < Sup
@x = "C"
end
Sup.new.test
Sub1.new.test
Sub2.new.test
Not the simplest but...
/Robert
Robert Feldt Guest
-
Bennett, Patrick #8
Re: Class variables - a surprising result
Obviously there's some confusion though Matz.
In most languages (C++, Java, Delphi, etc.), class variables (static's)
are scoped by the *class*, not the entire inheritance chain.
It's just... different. Once people understand it, it's fine, bug I
definitely don't think it's *obvious*.
-----Original Message-----
From: Yukihiro Matsumoto [mailto:matz@ruby-lang.org]
Sent: Thursday, August 21, 2003 10:50 AM
To: ruby-talk ML
Subject: Re: Class variables - a surprising result
Hi,
In message "Re: Class variables - a surprising result"
on 03/08/21, David Heinemeier Hansson <david@loudthinking.com>
writes:
|> Class variable allocation is per class scope, not per subclass scope.
|> Sub1, Sub2 and Sup really do share their class variables. Now don't
|> ask me for the "why exactly"...
|
|I was fooled by this as well. I don't know why I intuitively would
|think that a subclass would get its own scope, but I did. Having your
|own scope as a subclass would be a really neat addition, though. But
|perhaps a reason from Matz would shed light?
They are variables. If you can't update values, how they can be
variables.
class Sup
@@x = "A" # declare @@x, set @@x as "A"
def test
print @@x
end
end
class Sub1 < Sup
@@x = "B" # set @@x as "B"
end
class Sub2 < Sup
@@x = "C" # set @@x as "C"
end
Sup.new.test # print the value of @@x ("C")
Sub1.new.test # ditto.
Sub2.new.test # ditto.
Class variables are like global variables whose scope is limited to the
inheritance tree.
matz.
Bennett, Patrick Guest
-
Dan Doel #9
Re: Class variables - a surprising result
Gawnsoft wrote:
You are correct. If you search the ruby-talk archives you'll find a>A class-instance variable is one in which the scope is specific to a
>given (sub)class.
>
>Am I correct in dimly recalling that Ruby has support for
>class-instance variables?
>
discussion almost the same as this
one. Bottom line was that you have to do something like this:
class Foo
def initialize
class << Foo
@class_instance_var = 'c'
end
end
def test
class << Foo
puts @class_instance_var
end
end
end
class Bar < Foo
def initialize
class << Bar
@class_instance_var = 55
end
end
def inc
class << Bar
@class_instance_var += 1
end
end
def test
class << Bar
puts @class_instance_var
end
end
end
foo1 = Foo.new
bar1 = Bar.new
bar2 = Bar.new
foo1.test
bar1.test
bar2.test
bar1.inc
bar1.test
bar2.test
This prints:
c
55
55
56
56
Dan Doel Guest
-
Kurt M. Dresner #10
Re: Class variables - a surprising result
> I have run into this because I'm working on a loans
Um, this screams "instance variables" to me...> system, and each item needs a unique id, which I've allocated as an
> error correcting code. This gives me 46000 items. But if I have to
> use the same class variable to number my users uniquely as well as
> the items they borrow, that uses up space in my limited range.
What does your class represent, a user or a loan?
-Kurt
Kurt M. Dresner Guest
-
Yukihiro Matsumoto #11
Re: Class variables - a surprising result
Hi,
In message "Re: Class variables - a surprising result"
on 03/08/22, Hugh Sasse Staff Elec Eng <hgs@dmu.ac.uk> writes:
|It would be nice to have variables like global variables limited to
|all instances of a class but not inherited, too.
I think it can be done by self.class trick given by Robert Feldt in
[ruby-talk:79783].
matz.
Yukihiro Matsumoto Guest
-
Yukihiro Matsumoto #12
Re: Class variables - a surprising result
Hi,
In message "Re: Class variables - a surprising result"
on 03/08/22, "Bennett, Patrick" <Patrick.Bennett@inin.com> writes:
|In most languages (C++, Java, Delphi, etc.), class variables (static's)
|are scoped by the *class*, not the entire inheritance chain.
As far as I know, C++ and Java do not have class variables. They have
static member variables, which can be either private, protected, or
public. I know nothing about Delphi.
matz.
Yukihiro Matsumoto Guest
-
Mark J. Reed #13
Re: Class variables - a surprising result
On Fri, Aug 22, 2003 at 03:47:33AM +0900, Yukihiro Matsumoto wrote:
.. . . which are not inherited, which is why it is surprising to many> Hi,
>
> In message "Re: Class variables - a surprising result"
> on 03/08/22, "Bennett, Patrick" <Patrick.Bennett@inin.com> writes:
>
> |In most languages (C++, Java, Delphi, etc.), class variables (static's)
> |are scoped by the *class*, not the entire inheritance chain.
>
> As far as I know, C++ and Java do not have class variables. They have
> static member variables,
that Ruby's @@variables are inherited.
-Mark
Mark J. Reed Guest
-
Bennett, Patrick #14
Re: Class variables - a surprising result
My point was that many programmar's mistake Ruby's 'class' variables as
equivalent to static variables (I did).
Obviously they're not, but I thought it was worth pointing out that it's
a source of confusion for some [like myself] (until they learn or are
told otherwise).
The fact that there were several messages about it (and several
mentioning they didn't know it worked that way [I didn't for one]) I
think it says something about
its confusing (or perhaps under-documented) nature.
Since you designed the langusge, I'm sure you're not the slightest bit
confused by it. So, I think you can be discounted when it comes to
tallying the votes on Ruby confusion. ;)
Cheers...
-----Original Message-----
From: Yukihiro Matsumoto [mailto:matz@ruby-lang.org]
Sent: Thursday, August 21, 2003 1:48 PM
To: ruby-talk ML
Subject: Re: Class variables - a surprising result
Hi,
In message "Re: Class variables - a surprising result"
on 03/08/22, "Bennett, Patrick" <Patrick.Bennett@inin.com> writes:
|In most languages (C++, Java, Delphi, etc.), class variables (static's)
|are scoped by the *class*, not the entire inheritance chain.
As far as I know, C++ and Java do not have class variables. They have
static member variables, which can be either private, protected, or
public. I know nothing about Delphi.
matz.
Bennett, Patrick Guest
-
Hal E. Fulton #15
Re: Class variables - a surprising result
----- Original Message -----
From: "Yukihiro Matsumoto" <matz@ruby-lang.org>
To: "ruby-talk ML" <ruby-talk@ruby-lang.org>
Sent: Thursday, August 21, 2003 1:47 PM
Subject: Re: Class variables - a surprising result
eyebrow.raise> Hi,
>
> In message "Re: Class variables - a surprising result"
> on 03/08/22, "Bennett, Patrick" <Patrick.Bennett@inin.com> writes:
>
> |In most languages (C++, Java, Delphi, etc.), class variables (static's)
> |are scoped by the *class*, not the entire inheritance chain.
>
> As far as I know, C++ and Java do not have class variables. They have
> static member variables, which can be either private, protected, or
> public. I know nothing about Delphi.
This is interesting, because I would have said, "Those are class
variables, they just don't CALL them that."
I learned OOP from Eiffel (Meyer's OOSC book) -- just the terminology
and concepts, I never actually coded in Eiffel.
Don't I recall hearing that Ruby's class variables are based on those
of Smalltalk? (I don't know Smalltalk.)
If so, maybe the confusion is just related to mildly differing
flavors of OOP.
For the record, I have always been confused by Ruby's class variables
also, thinking that they should belong to the class and not the
hierarchy.
Hal
Hal E. Fulton Guest
-
Michael Campbell #16
Re: Class variables - a surprising result
> > As far as I know, C++ and Java do not have class variables. They have
>> > static member variables,
> .. . . which are not inherited, which is why it is surprising to many
> that Ruby's @@variables are inherited.
What do you mean by "not inherited"... I'm sure you're correct, but I'm
confused:
C:\tmp>cat Sub.java
class Base {
static int B = 1;
}
public class Sub extends Base {
public static void main(String[] args) {
System.out.println("Sub.B = " + Sub.B);
}
}
C:\tmp>javac Sub.java
C:\tmp>java Sub
Sub.B = 1
Michael Campbell Guest
-
Robert Feldt #17
Re: Class variables - a surprising result
Hal E. Fulton <hal9000@hypermetrics.com> skrev den Fri, 22 Aug 2003
03:58:13 +0900:
FTR, I've also been bitten by this. For me I think the problem> For the record, I have always been confused by Ruby's class variables
> also, thinking that they should belong to the class and not the
> hierarchy.
>
is their name; "class variables" just sounds like they would belong
to only the class. But of course subclasses also "belong" to that
class so there is some logic to it.
If they were more common I'd vote for adding more syntax (@@@x :))
but I tend to use both of them seldomly so don't really see the need.
Maybe this "quirk" should be added (or already have been) to some wiki page
for newcomers? Or is it obvious to everyone else?
Regards,
Robert Feldt
Robert Feldt Guest
-
Ben Giddings #18
Re: Class variables - a surprising result
Mark J. Reed wrote:
I'm one of them too. Is there a reason that they're implemented the way> .. . . which are not inherited, which is why it is surprising to many
> that Ruby's @@variables are inherited.
they are? Is it ease of implementation? Based on a different OO
paradigm? To me it violates the Principle of Least Surprise.
If I create a class inheriting from FooBar, it seems to me that it's
dangerous that I can break FooBar and all of its other subclasses by
doing what appears to be "declaring a class variable" because in reality
I'm "changing a class variable defined in a superclass".
Ben
Ben Giddings Guest
-
Mark J. Reed #19
Re: Class variables - a surprising result
On Fri, Aug 22, 2003 at 04:23:12AM +0900, Michael Campbell wrote:
You're only confused because you're assuming I'm correct. :) I> What do you mean by "not inherited"... I'm sure you're correct, but I'm
> confused:
was mistaken; I was thinking of other oddities with static members
and inheritance.
-Mark
Mark J. Reed Guest
-
Hugh Sasse Staff Elec Eng #20
Re: Class variables - a surprising result
On Fri, 22 Aug 2003, Kurt M. Dresner wrote:
Each has an instance var holding its number. Somewhere I must keep>> > I have run into this because I'm working on a loans
> > system, and each item needs a unique id, which I've allocated as an
> > error correcting code. This gives me 46000 items. But if I have to
> > use the same class variable to number my users uniquely as well as
> > the items they borrow, that uses up space in my limited range.
> Um, this screams "instance variables" to me...
the next available number, in such a way that the new item gets a
different one.
Now I've put it in those terms I might be better having a factory
class which has an instance var for the number, and calls the
constructor for the object I want numbered with that fresh
number....
... Item.new(@next_free) ...
Why didn't I think of that before? Keep the number somewhere else
than the class I want to count.I have users, loans, and items to be loaned. The loans aren't>
> What does your class represent, a user or a loan?
numberd, just the users and items.Hugh>
> -Kurt
>
>
Hugh Sasse Staff Elec Eng Guest



Reply With Quote

