[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

[newby] class variables and class instance variable?

Lionel Thiry

3/12/2005 2:40:00 PM

Hello.

class Test
@a = "value"

def self.a
@a
end

def initialize
@@a = "value2"
end

def a
@@a
end
end

puts Test.a # output: value
puts Test.new.a # output: value2

I don't understand (and I'm quite surprised), what is the difference in terms of
OO design between class variables, the @@a in the example above, and class
instance variables, the @a in the example?

Thanks in advance,
Lionel Thiry
46 Answers

Florian Gross

3/12/2005 6:21:00 PM

0

Lionel Thiry wrote:

> class Test
> @a = "value"
>
> def self.a
> @a
> end
>
> def initialize
> @@a = "value2"
> end
>
> def a
> @@a
> end
> end
>
> puts Test.a # output: value
> puts Test.new.a # output: value2
>
> I don't understand (and I'm quite surprised), what is the difference in
> terms of OO design between class variables, the @@a in the example
> above, and class instance variables, the @a in the example?

Currently class variables are also shared between different classes that
are part of the same inheritance tree. IMHO this is a rarely needed
feature and you're better off using regular instance variables on the
class (and referring to them via self.class.var from an instance).

Lionel Thiry

3/12/2005 10:54:00 PM

0

Florian Gross wrote:
> Lionel Thiry wrote:

>> I don't understand (and I'm quite surprised), what is the difference
>> in terms of OO design between class variables, the @@a in the example
>> above, and class instance variables, the @a in the example?
>
>
> Currently class variables are also shared between different classes that
> are part of the same inheritance tree.
I ignored that. *doing some testing* My! You're right.

> IMHO this is a rarely needed
> feature and you're better off using regular instance variables on the
> class (and referring to them via self.class.var from an instance).

I totally agree.

Thanks a lot,
Lionel Thiry

WoNáDo

3/13/2005 1:25:00 PM

0

--
Wolfgang Nádasi-Donner
wonado@donnerweb.de
"Lionel Thiry" <lthiryidontwantspam@skynetnospam.be> schrieb im Newsbeitrag
news:4232ff57$0$30162$ba620e4c@news.skynet.be...
> Hello.
>
> class Test
> @a = "value"
>
> def self.a
> @a
> end
>
> def initialize
> @@a = "value2"
> end
>
> def a
> @@a
> end
> end
>
> puts Test.a # output: value
> puts Test.new.a # output: value2
>
> I don't understand (and I'm quite surprised), what is the difference in
terms of
> OO design between class variables, the @@a in the example above, and class
> instance variables, the @a in the example?
>
> Thanks in advance,
> Lionel Thiry

The class variable ("@@") belongs to the class object, while the instance
variable (@) belongs to the instanciated object. A short example. May be you
want to count how many objects are created based on a class. If you want to
avoid global variables ($), which is a very good decision, you can use class
variables. Using instance variables will not work.

>>>>> Example >>>>>
class Mytest
@@n_of_Mytest = 0
def initialize
@@n_of_Mytest += 1
end
def Mytest.n_of_Mytest
@@n_of_Mytest
end
end

puts Mytest.n_of_Mytest
a = Mytest.new
puts Mytest.n_of_Mytest
b = Mytest.new
c = Mytest.new
puts Mytest.n_of_Mytest
d = Mytest.new
e = Mytest.new
f = Mytest.new
puts Mytest.n_of_Mytest
>>>>> Output >>>>>
0
1
3
6
>>>>> End of Example >>>>>

O.K.?


ts

3/13/2005 1:32:00 PM

0

>>>>> "W" == Wolfgang Nádasi-Donner <wonado@donnerweb.de> writes:

>>>>> Example >>>>>
W> class Mytest
W> @@n_of_Mytest = 0

svg% cat b.rb
#!/usr/local/bin/ruby
class Mytest
@n_of_Mytest = 0

def initialize
self.class.instance_eval { @n_of_Mytest += 1}
end

def Mytest.n_of_Mytest
@n_of_Mytest
end
end

puts Mytest.n_of_Mytest
a = Mytest.new
puts Mytest.n_of_Mytest
b = Mytest.new
c = Mytest.new
puts Mytest.n_of_Mytest
d = Mytest.new
e = Mytest.new
f = Mytest.new
puts Mytest.n_of_Mytest
svg%

svg% b.rb
0
1
3
6
svg%




--

Guy Decoux

Florian Gross

3/13/2005 1:36:00 PM

0

Wolfgang Nádasi-Donner wrote:

> The class variable ("@@") belongs to the class object, while the instance
> variable (@) belongs to the instanciated object. A short example. May be you
> want to count how many objects are created based on a class. If you want to
> avoid global variables ($), which is a very good decision, you can use class
> variables. Using instance variables will not work.

It will. Note that the poster said "class instance variable" which is
the instance variable of a Class. Classes are instances of Class and
Class inherits from Module which inherits from Object so classes are
objects as well:

class Foo
@counter = 0
class << self
attr_accessor :counter
end

def initialize()
self.class.counter += 1
end
end

Foo.counter # => 0
5.times { Foo.new }
Foo.counter # => 5

WoNáDo

3/13/2005 5:07:00 PM

0

--
Wolfgang Nádasi-Donner
wonado@donnerweb.de
"Florian Gross" <flgr@ccan.de> schrieb im Newsbeitrag
news:39itt7F5tgm5bU1@individual.net...
> Wolfgang Nádasi-Donner wrote:
>
> > The class variable ("@@") belongs to the class object, while the
instance
> > variable (@) belongs to the instanciated object. A short example. May be
you
> > want to count how many objects are created based on a class. If you want
to
> > avoid global variables ($), which is a very good decision, you can use
class
> > variables. Using instance variables will not work.
>
> It will. Note that the poster said "class instance variable" which is

*****************************************************
Ooops - need new glasses, I believe ;-) - Forget my example, please.
I often switch between Ruby an C#. This results in some confusion.
*****************************************************

> the instance variable of a Class. Classes are instances of Class and
> Class inherits from Module which inherits from Object so classes are
> objects as well:
>
> class Foo
> @counter = 0
> class << self
> attr_accessor :counter
> end
>
> def initialize()
> self.class.counter += 1
> end
> end
>
> Foo.counter # => 0
> 5.times { Foo.new }
> Foo.counter # => 5


Lionel Thiry

3/13/2005 5:09:00 PM

0

>>>>>>Example >>>>>
>
> class Mytest
> @@n_of_Mytest = 0
> def initialize
> @@n_of_Mytest += 1
> end
> def Mytest.n_of_Mytest
> @@n_of_Mytest
> end
> end
>
> puts Mytest.n_of_Mytest
> a = Mytest.new
> puts Mytest.n_of_Mytest
> b = Mytest.new
> c = Mytest.new
> puts Mytest.n_of_Mytest
> d = Mytest.new
> e = Mytest.new
> f = Mytest.new
> puts Mytest.n_of_Mytest
>
>>>>>>Output >>>>>
>
> 0
> 1
> 3
> 6
>
>>>>>>End of Example >>>>>
>
>
> O.K.?
>
>

I've tested your code and I've been surprised that it actually worked. If I
correctly understand the mechanism, it's like the class object and its instances
are able to access class variables through '@@'. Undubitably, I know now why I
couldn't get along with that feature.

Honestly, I largely prefer to think of classes as objects and use the class
instance variables when I want to share variables between instances. Using '@@'
doesn't seem reliable for me, as IMHO it violates some important OO principles,
the kind that if not followed leads to very embarrassing problems.

Thanks for your help,
Lionel Thiry

WoNáDo

3/13/2005 5:31:00 PM

0

--
Wolfgang Nádasi-Donner
wonado@donnerweb.de
"Florian Gross" <flgr@ccan.de> schrieb im Newsbeitrag
news:39gq83F620eslU2@individual.net...
> Lionel Thiry wrote:
>
> > class Test
> > @a = "value"
> >
> > def self.a
> > @a
> > end
> >
> > def initialize
> > @@a = "value2"
> > end
> >
> > def a
> > @@a
> > end
> > end
> >
> > puts Test.a # output: value
> > puts Test.new.a # output: value2
> >
> > I don't understand (and I'm quite surprised), what is the difference in
> > terms of OO design between class variables, the @@a in the example
> > above, and class instance variables, the @a in the example?
>
> Currently class variables are also shared between different classes that
> are part of the same inheritance tree. IMHO this is a rarely needed
> feature and you're better off using regular instance variables on the
> class (and referring to them via self.class.var from an instance).

Where is this described? - It is dangerous if one doesn't know this.

>>> Example >>>
class Animal
@@born = 0
def initialize
@@born += 1
puts "a new animal"
end
def Animal.born
@@born
end
end

class Dog<Animal
@@born = 0
def initialize
@@born += 1
puts "a new dog"
end
def Dog.born
@@born
end
end

class Cat<Animal
@@born = 0
def initialize
@@born += 1
puts "a new cat"
end
def Cat.born
@@born
end
end

print "#{Cat.born} cats, #{Dog.born} dogs, #{Animal.born} animals\n"
2.times{Dog.new}
print "#{Cat.born} cats, #{Dog.born} dogs, #{Animal.born} animals\n"
3.times{Cat.new}
print "#{Cat.born} cats, #{Dog.born} dogs, #{Animal.born} animals\n"
>>> Output >>>
0 cats, 0 dogs, 0 animals
a new dog
a new dog
2 cats, 2 dogs, 2 animals
a new cat
a new cat
a new cat
5 cats, 5 dogs, 5 animals
>>> End of Example >>>


ts

3/13/2005 5:42:00 PM

0

>>>>> "W" == Wolfgang Nádasi-Donner <wonado@donnerweb.de> writes:

>>>> Output >>>
W> 0 cats, 0 dogs, 0 animals
W> a new dog
W> a new dog
W> 2 cats, 2 dogs, 2 animals
W> a new cat
W> a new cat
W> a new cat
W> 5 cats, 5 dogs, 5 animals
>>>> End of Example >>>

With this version of ruby

uln% ruby -v
ruby 1.9.0 (2005-03-14) [x86_64-linux]
uln%

The result is

0 cats, 0 dogs, 0 animals
a new dog
a new dog
0 cats, 2 dogs, 0 animals
a new cat
a new cat
a new cat
3 cats, 2 dogs, 0 animals


--

Guy Decoux

Florian Gross

3/13/2005 6:25:00 PM

0

ts wrote:

> With this version of ruby
>
> uln% ruby -v
> ruby 1.9.0 (2005-03-14) [x86_64-linux]
> uln%
>
> The result is
>
> 0 cats, 0 dogs, 0 animals
> a new dog
> a new dog
> 0 cats, 2 dogs, 0 animals
> a new cat
> a new cat
> a new cat
> 3 cats, 2 dogs, 0 animals

So the behavior has been changed to lookup by surrounding module/class
on method definition time?