On 01/22/2011 10:50 PM, RichardOnRails wrote:
The following works, but I’d prefer not to have to class values:
class Z
def self.show_z
@@zz ||= 0; @@zz += 1
puts @@zz
end
end
Z.show_z # => 1
Z.show_z # => 2
Replace the @@'s with @'a so that you use a class instance variable
instead. In this case it works effectively the same while avoiding the
nasty class variables.
but it doesn’t pass muster with Ruby 1.8.6. I get a complaint about
the first line in show_y, which makes no sense IMHO:
TestOrEqual_operator.rb:18:in show_y': undefined method
+’
for :y:Symbol (NoMethodError)
from TestOrEqual_operator.rb:21
The error is ultimately the result of the way you initialized your Hash
instance. By passing :y to the new method, you arranged for any
uninitialized key referenced within the hash to have the symbol :y as a
value. Therefore,
$h[:y] ||= 0
doesn’t do anything because $h[:y] has a value of :y by default. The
next statement then attempts to increment the value of $h[:y] by 1 and
fails because that value is :y and the + method is not defined for
Symbols. If what I’m saying isn’t exactly clear, try this:
h = Hash.new(:howdy)
puts h[‘Say hello like a Texan!’]
puts h[‘Now say hello like a John Wayne!’]
You could avoid this particular problem by simply setting $h to {}
rather than calling Hash.new(:y). But why is a hash necessary for this
at all??? You could just as easily do this:
def show_y
$y ||= 0
$y += 1
puts $y
end
This still leaves you using a global, but it’s much simpler. More
importantly, it works. 
Also, I’d be able to use a succinct version of this without resorting
to globals.
Without knowing more about the problem you’re trying to solve, it’s hard
to provide a better response. Apparently, you want to call a method
that automatically initializes some state when needed and then modify
and preserve that state between subsequent calls to that method. That
state, be it a number as in your examples here or something else, has to
be stored somewhere.
I’m not a fan of globals in general, so I would choose to keep the state
in a class as you did in your first example.
-Jeremy