[lnkForumImage]
TotalShareware - Download Free Software

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


 

Forums >

comp.lang.ruby

Delegating class methods

arcadio

3/1/2009 8:33:00 PM

Hi all,

how would you forward calls from class methods to a class atribute?
Like in:

class Foo
@@hash = {}

def self.size
@@hash.size
end
end

I have to delegate a fairly large number of calls to an attribute. I'm
currently using method_missing, but I was wondering if there was a
cleaner way to do that as the method names are known at load time. I
didn't find any using the standard library. Perhaps using some
metaprogramming.

Thanks!
16 Answers

Albert Schlef

3/2/2009 6:08:00 AM

0

Arcadio Rubio garcía wrote:
> Hi all,
>
> how would you forward calls from class methods to a class atribute?

You can do the following:

class Foo
@one = 1
@two = 2
@three = 3

class << self
attr_accessor :one, :two, :Tthee
end
end

(Why are you doing '@@' instead of '@'?)
--
Posted via http://www.ruby-....

Albert Schlef

3/2/2009 6:11:00 AM

0

Albert Schlef wrote:
> You can do the following:
>
> class Foo
> @one = 1
> @two = 2
> @three = 3
>
> class << self
> attr_accessor :one, :two, :Tthee
> end
> end
>
> (Why are you doing '@@' instead of '@'?)

BTW, there's some glitch here. Let's say you inherit from Foo:

class Momo < Foo
end

puts Momo.one # won't print "1" !!!

The assignments to the attirbutes (in Foo's body) are happening in Foo's
bag, not in Momo's bag
--
Posted via http://www.ruby-....

Ryan Davis

3/2/2009 6:48:00 AM

0


On Mar 1, 2009, at 12:33 , abc wrote:

> how would you forward calls from class methods to a class atribute?

I'm not thrilled that you have to use a class method to access the
attribute, but this works:

> class Foo
> extend SingleForwardable
> def self.hash; @@hash ||= {}; end
> def_delegators :hash, :size, :keys
> end
>
> p Foo.size
> p Foo.keys

It'd be ideal if you could use :@@hash for the delegators line, but I
couldn't get that to work easily.


Ryan Davis

3/2/2009 6:49:00 AM

0


On Mar 1, 2009, at 22:08 , Albert Schlef wrote:

> (Why are you doing '@@' instead of '@'?)

Because, the OP wanted to use class vars, not class instance vars.


-lim-

3/2/2009 8:19:00 AM

0

> BTW, there's some glitch here. Let's say you inherit from Foo:

I'm not sure this can really be called a glitch because that's simply
the way self.instance-variables (or whatever their correct name is)
work. One solution would be to create a inherited class method that
copies the variables from the super class to the subclass.

class Foo
@one = 1
@two = 2
@three = 3

class << self
attr_accessor :one, :two, :three

def inherited(sub)
sub.one = one
sub.two = two
sub.three = three
end
end
end

class Momo < Foo
end

Momo.one #=> 1


That's cumbersome of course and it would be great if ruby had a
construct to do this automatically with having to define an inherited
hook.

--
Leo

The end is here -->

arcadio

3/2/2009 11:02:00 AM

0

I'm the OP. Thank you all for your replies.

Sorry if the question wasn't clear enough. I wanted to register all
the instances of a class, so the original idea was to use a hash class
variable to do that.

Of course there are a number of gotchas if you want to make the code
concise using this approach, so an alternative solution is to declare
another class, make it a Singleton and use it for that purpose.

I'm not a seasoned Ruby programmer, but I think I was totally right in
the idea of using class variables (@@hash). I cannot see why some
people are surprised. I'd be very happy if somebody could shed some
light on the issue, because maybe I'm missing something...

Ryan Davis

3/2/2009 11:11:00 AM

0


On Mar 2, 2009, at 03:05 , abc wrote:

> I'm not a seasoned Ruby programmer, but I think I was totally right in
> the idea of using class variables (@@hash).

No, using a class var there was totally appropriate.

In the case of your design, depending on what you're actually trying
to accomplish by registering every instance, you can forgo the
registration hash and use:

ObjectSpace.each_object(YourClass) { |obj| ... }

That only iterates live objects and also has the disadvantage of not
working in jruby or rubinius (yet?).


Robert Dober

3/2/2009 11:58:00 AM

0

On Mon, Mar 2, 2009 at 7:49 AM, Ryan Davis <ryand-ruby@zenspider.com> wrote:
>
> On Mar 1, 2009, at 22:08 , Albert Schlef wrote:
>
>> (Why are you doing '@@' instead of '@'?)
>
> Because, the OP wanted to use class vars, not class instance vars.
Yes but we do not allow this (easily) ;)

Seriously OP are you sure you want class variables??
And if you're answer is yes, let me ask you the following question:
Are you sure you want to use class variables??
And if you are not I am happily going further in explaining why ;).

Cheers
Robert
>
>
>



--
There are some people who begin the Zoo at the beginning, called
WAYIN, and walk as quickly as they can past every cage until they get
to the one called WAYOUT, but the nicest people go straight to the
animal they love the most, and stay there. ~ A.A. Milne (from
Winnie-the-Pooh)

Robert Dober

3/2/2009 12:01:00 PM

0

On Mon, Mar 2, 2009 at 12:05 PM, abc <arcadiorubiogarcia@gmail.com> wrote:
> I'm the OP. Thank you all for your replies.
>
> Sorry if the question wasn't clear enough. I wanted to register all
> the instances of a class, so the original idea was to use a hash class
> variable to do that.
>
> Of course there are a number of gotchas if you want to make the code
> concise using this approach, so an alternative solution is to declare
> another class, make it a Singleton and use it for that purpose.
>
> I'm not a seasoned Ruby programmer, but I think I was totally right in
> the idea of using class variables (@@hash). I cannot see why some
> people are surprised. I'd be very happy if somebody could shed some
> light on the issue, because maybe I'm missing something...
>
oops sorry, you made your point already.
Well if you use class variables they will be shared by all your
subclasses, if that is what you want, perfect.

Often one does not want that behavior, hence the surprise ;), because
a superclass generally shall not know about its subclasses.
Implications on maintenance and reuse are heavy! But there are cases
where it is fine, just ponder the question carefully :)

Cheers
Robert
>



--
There are some people who begin the Zoo at the beginning, called
WAYIN, and walk as quickly as they can past every cage until they get
to the one called WAYOUT, but the nicest people go straight to the
animal they love the most, and stay there. ~ A.A. Milne (from
Winnie-the-Pooh)

lasitha

3/2/2009 2:25:00 PM

0

On Mon, Mar 2, 2009 at 4:35 PM, abc <arcadiorubiogarcia@gmail.com> wrote:
> I'm the OP. Thank you all for your replies.

Hello OP :)

> I'm not a seasoned Ruby programmer, but I think I was totally right in
> the idea of using class variables (@@hash). I cannot see why some
> people are surprised. I'd be very happy if somebody could shed some
> light on the issue, because maybe I'm missing something...

There is a school of thought that eigenclass [1] instance variables
are generally preferred over @@class_variables. Folks coming to ruby
from other languages often miss the distinction but you'll find many
expos=E9s on this [2], including in the Pickaxe.

I personally like eigenclass variables - they provide all the
capability of class variables, fit elegantly into ruby's object model
and follow all the rules of instance variables. So i don't ever bother
with class vars.

It's important to note this is completely orthogonal to the discussion
about whether it's appropriate to use any class-level state at all.
That has been adequately addressed in this thread already, but it's
possible some of the questioning about class variables may actually
have revolved around whether to use eigenclass variables instead.

Solidarity,
lasitha.

[1] a.k.a singleton class, metaclass, etc.
[2] http://tinyurl....
http://tinyurl....
http://tinyurl....
http://tinyurl....