[lnkForumImage]
TotalShareware - Download Free Software

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


 

Forums >

comp.lang.ruby

Class (not instance) Initializer

Greg Willits

6/11/2008 10:30:00 PM

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
--
Posted via http://www.ruby-....

4 Answers

Tim Hunter

6/11/2008 10:39:00 PM

0

Greg Willits wrote:
> 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

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

--
RMagick: http://rmagick.ruby...
RMagick 2: http://rmagick.ruby...rmagick2.html

Greg Willits

6/11/2008 10:51:00 PM

0

Tim Hunter 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

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

Paul McMahon

6/12/2008 12:44:00 AM

0

> 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
...

Robert Dober

6/12/2008 10:23:00 AM

0

On Thu, Jun 12, 2008 at 12:50 AM, Greg Willits <lists@gregwillits.ws> wrote:
> Tim Hunter 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
>
> --
> Posted via http://www.ruby-....
>
>


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 ;)

--------------------------- 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.blo...

---
As simple as possible, but not simpler.
Albert Einstein