Method usable as class and instance method

M

Michael Perle

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
 
R

Robert Klemme

Michael said:
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
 
M

Michael Perle

Robert said:
Michael said:
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
 
R

Robert Klemme

Michael Perle said:
Robert said:
Michael said:
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
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
 
M

Michael Perle

Robert said:
Michael Perle said:
Robert said:
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
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top