[lnkForumImage]
TotalShareware - Download Free Software

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


 

Forums >

comp.lang.ruby

Method usable as class and instance method

Michael Perle

5/19/2006 8:11:00 PM

Hi Ruby Folks,

What do you think would be the best way
to provide one and the same method as a
class method and as an instance method.

I did not find any examples, and am asking myself
if the call of the class method from the instance
method is the real thing.

1. Is there a better way?
2. Does it make any difference if I use
'def self.method' or 'def ClassName.method'
(= "hard-coding" the class name).
3. Why does self.method not work in the def of
an instance method? (See 2nd comment below.)

--- Start of sample code ---

class TextCase

def self.up(txt)
# Would TextCase.up(txt) be any different?
txt.upcase
end

def up(txt)
TextCase.up(txt)
# Why not self.up(txt)?
# Tried it and got a 'stack level too deep ...' error
end

end

tc = TextCase.new
puts tc.up('abc')
puts TextCase.up('def')

--- End of sample code ---

Thank you very much for your ideas.
MP
4 Answers

Robert Klemme

5/20/2006 8:27:00 AM

0

Michael Perle wrote:
> Hi Ruby Folks,
>
> What do you think would be the best way
> to provide one and the same method as a
> class method and as an instance method.
>
> I did not find any examples, and am asking myself
> if the call of the class method from the instance
> method is the real thing.
>
> 1. Is there a better way?

There are several ways but before that I'd ask what you want to
accomplish here. Usually there is a separation between class methods
and instance methods for a reason. If you just want to bundle a set of
algorithms you should consider using a module instead. You can then
extend whatever instance you want them to be or include it in a class.

A common way to do this is a module

module TextCaseAlgorithms
def up()...end
end

class TextCase
include TextCaseAlgorithms
extend TextCaseAlgorithms
end

TextCase.up # works
TextCase.new.up # works as well

> 2. Does it make any difference if I use
> 'def self.method' or 'def ClassName.method'
> (= "hard-coding" the class name).

Hard coding the class name is more error prone as it will break once you
rename the class in the file. Otherwise they are the same because they
refer to the exact same instance.

> 3. Why does self.method not work in the def of
> an instance method? (See 2nd comment below.)
>
> --- Start of sample code ---
>
> class TextCase
>
> def self.up(txt)
> # Would TextCase.up(txt) be any different?
> txt.upcase
> end
>
> def up(txt)
> TextCase.up(txt)
> # Why not self.up(txt)?
> # Tried it and got a 'stack level too deep ...' error

You created a recursion without terminating condition: the method calls
itself, calls itself, calls itself...

Alternatively you can do
self.class.up(txt)

This is slightly different because the class is not hardcoded and
although subclasses of TextCase inherit the class method they may
override it.

> end
>
> end
>
> tc = TextCase.new
> puts tc.up('abc')
> puts TextCase.up('def')
>
> --- End of sample code ---
>
> Thank you very much for your ideas.
> MP

Also, when searching the archives of ruby-talk you'll find plenty
discussions of this topic.

Cheers

robert

Michael Perle

5/21/2006 2:58:00 PM

0

Robert Klemme wrote:
> Michael Perle wrote:
>
>> Hi Ruby Folks,
>>
>> What do you think would be the best way
>> to provide one and the same method as a
>> class method and as an instance method.
[...]
> There are several ways but before that I'd ask what you want to
> accomplish here.

The idea was to provide a method out of one class
to those who need only these methods and not
necessarily an instance.
Numbering.roman(12) should deliver 'XII'.

> A common way to do this is a module

Thanks. Agree. I had locked in myself to
this one and only class definition.

Thinking a bit further, it could make sense
add a method like 'to_roman' or so to the
class Integer at runtime. Would that go too
far or is that indeed the rubyish way?

MP

Robert Klemme

5/22/2006 8:54:00 PM

0

Michael Perle <michael_perle@yahoo.com> wrote:
> Robert Klemme wrote:
>> Michael Perle wrote:
>>
>>> Hi Ruby Folks,
>>>
>>> What do you think would be the best way
>>> to provide one and the same method as a
>>> class method and as an instance method.
> [...]
>> There are several ways but before that I'd ask what you want to
>> accomplish here.
>
> The idea was to provide a method out of one class
> to those who need only these methods and not
> necessarily an instance.
> Numbering.roman(12) should deliver 'XII'.

You can as well create a class Roman with a proper constructor and a to_s
method. In that case you should also implement <=>, coerce, to_i, to_int,
hash and probably some more. You can than also implement Kernel.Roman()
like Float() etc.

irb(main):002:0> Float("1.2")
=> 1.2

>> A common way to do this is a module
>
> Thanks. Agree. I had locked in myself to
> this one and only class definition.
>
> Thinking a bit further, it could make sense
> add a method like 'to_roman' or so to the
> class Integer at runtime. Would that go too
> far or is that indeed the rubyish way?

No that's perfectly ok.

Kind regards

robert

Michael Perle

5/23/2006 7:37:00 PM

0

Robert Klemme wrote:
> Michael Perle <michael_perle@yahoo.com> wrote:
>
>> Robert Klemme wrote:
>>
>>> Michael Perle wrote:
>>>
>>>> Hi Ruby Folks,
>>>>
>>>> What do you think would be the best way
>>>> to provide one and the same method as a
>>>> class method and as an instance method.
>>
>> [...]
>>
>>> There are several ways but before that I'd ask what you want to
>>> accomplish here.
>>
>>
>> The idea was to provide a method out of one class
>> to those who need only these methods and not
>> necessarily an instance.
>> Numbering.roman(12) should deliver 'XII'.
>
>
> You can as well create a class Roman with a proper constructor and a
> to_s method. In that case you should also implement <=>, coerce, to_i,
> to_int, hash and probably some more. You can than also implement
> Kernel.Roman() like Float() etc.

[...]

>> Thinking a bit further, it could make sense
>> add a method like 'to_roman' or so to the
>> class Integer at runtime. Would that go too
>> far or is that indeed the rubyish way?
>
> No that's perfectly ok.

The Kernel.Roman idea and the modification of Integer
seem to be my entry into the zone where Ruby is
different -- the differentiator being a definitely
a strength.

Thank you for pushing me forward into this direction.

MP