Class (not instance) Initializer

I would like to populate a class variable using a method

class SomeThing
@@some_data
populate_some_data

def populate_some_data
end
end

I expected that prefixing the method with self would work. It doesn’t.


self.populate_some_data

def self.populate_some_data
end

Poking around in a couple books I don’t see anything that addresses
this. What’s the correct syntax for this? Or, if there is no way to run
a method, what’s the best way to pull a trigger to have @@some_data
populated the first time any object of SomeThings is instantiated?

– gw

Greg W. wrote:

this. What’s the correct syntax for this? Or, if there is no way to run
a method, what’s the best way to pull a trigger to have @@some_data
populated the first time any object of SomeThings is instantiated?

– gw

Well, if you want to wait to do the initialization until the first
object is created, then something like this might work:

def initialize
populate_some_data if @@some_data == nil

end

But if all you want to do it initialize @@some_data, just put the
initialization code in the class definition:

class SomeThing
@@some_data = [1,2,3]
def initialize

end
end

Ruby will execute the code as it creates the class. Try this:

~$ irb
irb(main):001:0> class SomeThing
irb(main):002:1> puts “Hiya!”
irb(main):003:1> end
Hiya!
=> nil

Tim H. wrote:

Well, if you want to wait to do the initialization until the first
object is created, then something like this might work:

def initialize
populate_some_data if @@some_data == nil

end

Duh. I should have figured that one out. Thanks.

– gw

I expected that prefixing the method with self would work. It doesn’t.


self.populate_some_data

def self.populate_some_data
end

Your issue here is that code within a class is executed a line at a
time, so populate_some_data is called before it is defined. Also, you
don’t need to use self when calling populate_some_data, as the method is
already called within the scope of the class (though this is just a
style issue). So the following code will work:


def self.populate_some_data
end
populate_some_data

On Thu, Jun 12, 2008 at 12:50 AM, Greg W. [email protected]
wrote:

– gw


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

It is most unfortunate that class variables are still advocated so much
:(.

The last but one line shows one of the problems of class variables,
they violate the principle that a base class shall never be touched by
the implementation of its subclasses - I know there is a classy name
for this but I forgot it :wink:

--------------------------- 8< ---------------------------
203/79 > cat class_vars.rb && ruby class_vars.rb

vim: sw=2 ts=2 ft=ruby expandtab tw=0 nu syn=on:

file: class_vars.rb

class Base
@@cvar=:Base
@cinstvar=:base
class << self
attr_reader :cinstvar
def cvar; @@cvar end
end
end

class Sub < Base
@@cvar = :Sub
@cinstvar = :sub
end

puts “@@cvar in Sub: #{Sub.cvar}”
puts “@cinstaver in Sub: #{Sub.cinstvar}”
puts "===“20
puts "@@cvar in Base: #{Base.cvar}

puts “@cinstaver in Base: #{Base.cinstvar}”

@@cvar in Sub: Sub
@cinstaver in Sub: sub

@@cvar in Base: Sub*
@cinstaver in Base: base

--------------------------- 8< ------------------------------------

So the basic advice is to use Class instance variables, in your case
that might be written as

class Something
@some_data = [1,2,3]
class << self; attr_reader :some_data end
end

you can of course access them directly in class methods either defined
with the self idiom

def self.print_data; puts @some_data end

or via the singleton class idiom

class << self
def print_data; puts @some_data end
end

HTH
Robert


http://ruby-smalltalk.blogspot.com/


As simple as possible, but not simpler.
Albert Einstein