Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Ruby > what is wrong with class variables? (newby)

Reply
Thread Tools

what is wrong with class variables? (newby)

 
 
weathercoach@gmail.com
Guest
Posts: n/a
 
      11-16-2007

Hello. I'm new to programming and new to ruby. I've recently
written a script and have asked people (including this group) about
components of the script. When people see that I'm using class
variables they ask me why and make a frowny face.

So as I'm trying to get a better understanding of ruby I ask what's
wrong with class variables? Or could it be how I've used them and not
a problem with class variables? I use class variables as a list where
I can add items for future reference. For example let's say I have a
class variable (@@over_quota) that holds the list of users who are
over quoata. Then I iterate through the passwd file and check each
users home directory and if they are over quota I toss them onto the
class variable (@@over_quoata). Once I've iterated through the
passwd file I see if anything is in my class variable
(@@over_quota)and then iterate over the class variable sending email
to each user who's over quoata.

I've recently (hour ago) learned about class instance variables and
I'm wondering if they are less frowned upon than class variables.
In the following example would it be better to use an class instance
variable over a class variable. From my perpective the end result
is the same.
#!/usr/bin/env ruby -w

class Simple
@@var = []
def Simple.append(l)
@@var << l
end
def Simple.return_var
@@var
end
end

one = Simple.append("fred")
puts Simple.return_var
two = Simple.append("tony")
puts Simple.return_var

../class_variable.rb
fred
fred
tony

#!/usr/bin/env ruby -w
class Simple
@var = []
def Simple.append(l)
@var << l
end
def Simple.return_var
@var
end
end

one = Simple.append("fred")
puts Simple.return_var
two = Simple.append("tony")
puts Simple.return_var

fred
fred
tony

Thanks in advance for your time!
Hopefully one day I'll be able to answer someone elses question!
G.
 
Reply With Quote
 
 
 
 
Brian Marick
Guest
Posts: n/a
 
      11-16-2007

On Nov 16, 2007, at 2:55 PM, http://www.velocityreviews.com/forums/(E-Mail Removed) wrote:
> So as I'm trying to get a better understanding of ruby I ask what's
> wrong with class variables?


There are probably profound philosophical reasons that they're wrong,
but I think the most convincing reason is experience. They were
invented a long time ago (late 70's, I believe), people used them,
and they turned out to cause problems. They made it harder to write a
program, leave it, come back to it, extend it, and have that work.
They made confusing bugs more likely. And (often) it's just as easy
to do without them.

One lesson I've learned the hard way is that it's almost always
better to use an instance than a class. For example, you have this:

> one = Simple.append("fred")
> puts Simple.return_var
> two = Simple.append("tony")
> puts Simple.return_var


I'd be tempted to do that if I knew -- absolutely knew -- that there
was never going to be more than one Simple. But I've learned to
prefer something like this:

simple = Simple.new
one = simple.append("fred")
puts simple.return_var
two = simple.append("tony")
puts simple.return_var

Why? Because almost *every* *time* I use the class instead of an
instance, I end up regretting it.

Notice that if you use the instance, you'll change your
implementation of Simple to this:

class Simple
def initialize
@var = []
end

def append(i)
@var << i
end

def return_var
@var
end
end

Class variable is gone. And you can start taking advantage of other
Ruby features. For example, you can use attributes to avoid writing
some code:

class Simple
attr_reader :var # replaces the def of return_var

def initialize
@var = []
end

def append(i)
@var << i
end

end


In what I guess you'd call the modern style of coding, people write
tests before writing the code. What that does is make long-term
unpleasantness into immediate unpleasantness. For example, class
variables make classes hard to test, so testing encourages you not to
use them.

Now for the blatant plug: I describe this style of coding in
_Everyday Scripting with Ruby_ <http://www.pragprog.com/titles/bmsft>.

-----
Brian Marick, independent consultant
Mostly on agile methods with a testing slant
www.exampler.com, www.exampler.com/blog, twitter.com/marick


 
Reply With Quote
 
 
 
 
weathercoach@gmail.com
Guest
Posts: n/a
 
      11-16-2007
>
> and they turned out to cause problems. They made it harder to write a
> program, leave it, come back to it, extend it, and have that work.
> They made confusing bugs more likely. And (often) it's just as easy


Brian.
Now I understand the frowny faces. Your explanation is great in
that I don't have to be a skilled programmer to comprehend your
point. Thank you very much for breaking it down like this.
I'll see if my boss will get me the book
Thanks again. G.



> to do without them.
>
> One lesson I've learned the hard way is that it's almost always
> better to use an instance than a class. For example, you have this:
>
> > one = Simple.append("fred")
> > puts Simple.return_var
> > two = Simple.append("tony")
> > puts Simple.return_var

>
> I'd be tempted to do that if I knew -- absolutely knew -- that there
> was never going to be more than one Simple. But I've learned to
> prefer something like this:
>
> simple = Simple.new
> one = simple.append("fred")
> puts simple.return_var
> two = simple.append("tony")
> puts simple.return_var
>
> Why? Because almost *every* *time* I use the class instead of an
> instance, I end up regretting it.
>
> Notice that if you use the instance, you'll change your
> implementation of Simple to this:
>
> class Simple
> def initialize
> @var = []
> end
>
> def append(i)
> @var << i
> end
>
> def return_var
> @var
> end
> end
>
> Class variable is gone. And you can start taking advantage of other
> Ruby features. For example, you can use attributes to avoid writing
> some code:
>
> class Simple
> attr_reader :var # replaces the def of return_var
>
> def initialize
> @var = []
> end
>
> def append(i)
> @var << i
> end
>
> end
>
> In what I guess you'd call the modern style of coding, people write
> tests before writing the code. What that does is make long-term
> unpleasantness into immediate unpleasantness. For example, class
> variables make classes hard to test, so testing encourages you not to
> use them.
>
> Now for the blatant plug: I describe this style of coding in
> _Everyday Scripting with Ruby_ <http://www.pragprog.com/titles/bmsft>.
>
> -----
> Brian Marick, independent consultant
> Mostly on agile methods with a testing slantwww.exampler.com,www.exampler.com/blog, twitter.com/marick


 
Reply With Quote
 
Raul Parolari
Guest
Posts: n/a
 
      11-16-2007

(E-Mail Removed) wrote:
> When people see that I'm using class
> variables they ask me why and make a frowny face.


Brian Marick wrote:
> There are probably profound philosophical reasons that they're wrong,
> but I think the most convincing reason is experience. They were
> invented a long time ago (late 70's, I believe), people used them,
> and they turned out to cause problems..


The trouble was (is?) that programmers used them to store 'State' that
was read and written by several components; the result was that the
complexity of the system (the number of possible 'states') grew
exponentially with each of those variables (of course, they are so easy
to use that they cut down the schedule at the beginning; these problems
are never only 'technical'..).

Furthermore, in Ruby a 'class variable' is visible across the whole
hierarchy of subclasses (a modification done anywhere impacts all);
therefore, the potential for trouble is high.

Having said that, now for the part that may be controversial: I think
that class varibles can be VERY USEFUL, if used correctly; for example,
when there is a quasi-static condition to be transmitted to a hierarchy
of classes. Rails uses them profusely, for example in
action_controller/base.rb,

------
# All requests are considered local by default, so everyone will
# be exposed to detailed debugging screens on errors. When the
# application is ready to go public, this should be set to false

@@consider_all_requests_local = true
cattr_accessor :consider_all_requests_local
-------

There are many variables like that, which propagate quasi-static
conditions to the whole hierarchy. Notice also how they are complemented
with a 'class attribute accessor', so that they are accessed via methods
(which allows one day to change the implementation, if necessary).

Personally, I think that this is simply splendid: maximizing the benefit
(cheap distribution of quasi-static info across a hierarchy), minimizing
the evils.

Rails does even something more interesting: sometimes we want the
benefits of a class variable - eg, to inherit its content from the
superclass - but we want to be able to change it privately in a class;
this is done via the 'class_inheritable_accessor' (which plays a
fundamental role to chain modules to the View).

In conclusion, I think that very few things in programming are totally
'evil' (or totally 'good'); it all depends from the context, the
purpose, and the intelligence of the programmer using them.
--
Posted via http://www.ruby-forum.com/.

 
Reply With Quote
 
Rick DeNatale
Guest
Posts: n/a
 
      11-17-2007
On Nov 16, 2007 6:19 PM, Raul Parolari <(E-Mail Removed)> wrote:
>
> (E-Mail Removed) wrote:
> > When people see that I'm using class
> > variables they ask me why and make a frowny face.

>
> Brian Marick wrote:
> > There are probably profound philosophical reasons that they're wrong,
> > but I think the most convincing reason is experience. They were
> > invented a long time ago (late 70's, I believe), people used them,
> > and they turned out to cause problems..

>
> The trouble was (is?) that programmers used them to store 'State' that
> was read and written by several components; the result was that the
> complexity of the system (the number of possible 'states') grew
> exponentially with each of those variables (of course, they are so easy
> to use that they cut down the schedule at the beginning; these problems
> are never only 'technical'..).
>
> Furthermore, in Ruby a 'class variable' is visible across the whole
> hierarchy of subclasses (a modification done anywhere impacts all);
> therefore, the potential for trouble is high.
>
> Having said that, now for the part that may be controversial: I think
> that class varibles can be VERY USEFUL, if used correctly; for example,
> when there is a quasi-static condition to be transmitted to a hierarchy
> of classes. Rails uses them profusely, for example in
> action_controller/base.rb,
>
> ------
> # All requests are considered local by default, so everyone will
> # be exposed to detailed debugging screens on errors. When the
> # application is ready to go public, this should be set to false
>
> @@consider_all_requests_local = true
> cattr_accessor :consider_all_requests_local
> -------
>
> There are many variables like that, which propagate quasi-static
> conditions to the whole hierarchy. Notice also how they are complemented
> with a 'class attribute accessor', so that they are accessed via methods
> (which allows one day to change the implementation, if necessary).
>
> Personally, I think that this is simply splendid: maximizing the benefit
> (cheap distribution of quasi-static info across a hierarchy), minimizing
> the evils.
>
> Rails does even something more interesting: sometimes we want the
> benefits of a class variable - eg, to inherit its content from the
> superclass - but we want to be able to change it privately in a class;
> this is done via the 'class_inheritable_accessor' (which plays a
> fundamental role to chain modules to the View).
>
> In conclusion, I think that very few things in programming are totally
> 'evil' (or totally 'good'); it all depends from the context, the
> purpose, and the intelligence of the programmer using them.


Great observations!

I've struggled with Ruby class variables myself. Of course I looked
at them in the light of my Smalltalk experience.

Smalltalk also has class variables which have the same kind of
visibility as in Ruby, class variables are visible to a sub-hierarchy
of Classes and their instances.

In Smalltalk they are (or at least used to be) used sparingly, and
almost always for static data. In effect they were used for the kind
of things you'd define as constants in a .h file.

The big difference that I can see between class variables in Ruby and
Smalltalk springs from the fact that while Smalltalk variable names
are declared, in Ruby they are introduced dynamically at first mention
during execution.

In Smalltalk the development environment would prevent redeclaration
of a class variable name, while in Ruby this can be done and causes
problems when a superclass creates a class variable which already
exists below, breaking the identity of the variable's scope.

And, yes, I think that overuse of class variables for changeable state
is problematic either in Smalltalk or Ruby, but hadn't thought about
that much until Raul so eloquently described it.

--
Rick DeNatale

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

 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Class A contains class B, class B points to class A Joseph Turian C++ 5 12-30-2005 03:24 PM
Nested Class, Member Class, Inner Class, Local Class, Anonymous Class E11 Java 1 10-12-2005 03:34 PM
A parameterized class (i.e. template class / class template) is not a class? christopher diggins C++ 16 05-04-2005 12:26 AM
[Rdoc-bug] wrong parent class using Mod::Class syntax Michael Neumann Ruby 1 11-08-2004 01:25 PM
Can't find class java.lang.NoClassDefFoundError. (Wrong class path?) qazmlp Java 6 07-11-2003 10:09 PM



Advertisments