# What does --can't define singleton method-- mean?

RubyNG.hello /.*/

mond:/pool/PROG/ruby # irb
irb(main):001:0> require "complex"
=> true
irb(main):002:0> c=Complex.new 1,1
=> Complex(1, 1)
irb(main):003:0> c.arg
=> 0.785398163397448
irb(main):004:0> c.angle
=> 0.785398163397448
irb(main):005:0> class << c
irb(main):006:1> def angle
irb(main):007:2> (arg/Math::PI)*180
irb(main):008:2> end
irb(main):009:1> end
TypeError: can't define singleton method "angle" for Complex
from (irb):6
irb(main):010:0> c.arg
=> 0.785398163397448
irb(main):011:0> c.angle
=> 45.0
irb(main):012:0>

what does TypeError means here?
can someone enlighten me
I have one more related question
I would like to have the angle method
to return the angle in degrees for each
Complex instance, how can I achieve it
the obvious didn't work for me

irb(main):014:0* class << Complex
irb(main):015:1> def angle
irb(main):016:2> (self.arg/Math::PI)*180
irb(main):017:2> end
irb(main):018:1> end
=> nil
irb(main):019:0> d=Complex.new 1,1
=> Complex(1, 1)
irb(main):020:0> d
=> Complex(1, 1)
irb(main):021:0> d.arg
=> 0.785398163397448
irb(main):022:0> d.angle
=> 0.785398163397448
irb(main):023:0>

Regards, Daniel

···

from :0

Daniel Schüle wrote:

irb(main):005:0> class << c
irb(main):006:1> def angle
irb(main):007:2> (arg/Math::PI)*180
irb(main):008:2> end
irb(main):009:1> end

Do you mean to add a method to an object?
This would work:
def c.angle
(arg/Math::PI)*180
end

I hope this will help.

···

TypeError: can't define singleton method "angle" for Complex
from (irb):6
from :0
irb(main):010:0> c.arg
=> 0.785398163397448
irb(main):011:0> c.angle
=> 45.0
irb(main):012:0>

what does TypeError means here?
can someone enlighten me
I have one more related question
I would like to have the angle method
to return the angle in degrees for each
Complex instance, how can I achieve it
the obvious didn't work for me

irb(main):014:0* class << Complex
irb(main):015:1> def angle
irb(main):016:2> (self.arg/Math::PI)*180
irb(main):017:2> end
irb(main):018:1> end
=> nil
irb(main):019:0> d=Complex.new 1,1
=> Complex(1, 1)
irb(main):020:0> d
=> Complex(1, 1)
irb(main):021:0> d.arg
=> 0.785398163397448
irb(main):022:0> d.angle
=> 0.785398163397448
irb(main):023:0>

Regards, Daniel

Hi,

At Sun, 6 Nov 2005 22:42:11 +0900,
Daniel Schüle wrote in [ruby-talk:164450]:

what does TypeError means here?

/* Numerics should be values; singleton_methods should not be added to them */

···

--

You're using the wrong syntax here. To re-open a class, just use
normal class definition syntax:

class Complex
def angle
arg/Math::PI*180.0
end
end

However, I would advise you to use a name like 'angle_in_degrees'
rather than override a basic function in this way. It will bite you
later when you include other libraries that expect angle in radians.

Regards,

Sean

···

On 11/6/05, Daniel Schüle <uval@rz.uni-karlsruhe.de> wrote:

irb(main):014:0* class << Complex

irb(main):005:0> class << c
irb(main):006:1> def angle
irb(main):007:2> (arg/Math::PI)*180
irb(main):008:2> end
irb(main):009:1> end
TypeError: can't define singleton method "angle" for Complex
from (irb):6
from :0
irb(main):010:0> c.arg
=> 0.785398163397448
irb(main):011:0> c.angle
=> 45.0

I think the error message is misleading, because

class << c
def angle;end
end

should add a singleton method to instance c
or overwrite the behavior of inherited method

as expected the behaviuor of c.angle is changed

it should not "define singleton method for Complex"

Regards, Daniel

/* Numerics should be values; singleton_methods should not be added to them */

Yes, but the problem is with irb

moulon% irb
irb(main):001:0> require 'complex'
=> true
irb(main):002:0> c = Complex.new(1, 1)
=> Complex(1, 1)
irb(main):003:0> c.angle
=> 0.785398163397448
irb(main):004:0> def c.angle() 12 end
TypeError: can't define singleton method "angle" for Complex
from (irb):4
irb(main):005:0> c.angle
=> 12
irb(main):006:0> d = Complex.new(1, 1)
=> Complex(1, 1)
irb(main):007:0> d.angle
=> 0.785398163397448
irb(main):008:0>
moulon%

Guy Decoux

Sean O'Halpin wrote:

> irb(main):014:0* class << Complex

You're using the wrong syntax here. To re-open a class, just use
normal class definition syntax:

I think Daniel was, correctly, trying to limit his change
to his own object. He didn't want to affect the class.

Using 'Coo' in place of 'Complex' works as he would have expected:

class Coo
def angle
90
end
end

myc = Coo.new
def myc.angle
88
end
p myc.angle #-> 88

alt_myc = Coo.new
# alternative-style definition to def myc.angle
class << alt_myc
def angle
22
end
end
p alt_myc.angle #-> 22

# Coo class remains unaffected
c = Coo.new
p c.angle #-> 90

Fortunately, the gurus stepped in with an explanation

daz

···

On 11/6/05, Daniel Schüle wrote:

Sean O'Halpin wrote:

irb(main):014:0* class << Complex

You're using the wrong syntax here. To re-open a class, just use
normal class definition syntax:

class Complex
def angle
arg/Math::PI*180.0
end
end

I found out that I also can use

Complex.class_eval do
def angle
arg / Math::PI * 180
end
end

this would "update" the method for all instances of Complex class

class << Complex
def angle; "angle"; end
end

would create singleton_method for Complex class itself
Complex.angle => "angle"

what is the advantage or typical use of having singleton method for a class?
I could imagine that since Complex is a Class it has some inherited methods from it .. and singleton method would belong only to Complex
nevertheless I can't find scenarious where I could use it
but I am a newbee

thanks to all for your replies

Daniel

···

On 11/6/05, Daniel Schüle <uval@rz.uni-karlsruhe.de> wrote:

Daniel Schüle wrote:

> irb(main):005:0> class << c
> irb(main):006:1> def angle
> irb(main):007:2> (arg/Math::PI)*180
> irb(main):008:2> end
> irb(main):009:1> end
> TypeError: can't define singleton method "angle" for Complex
> from (irb):6
> from :0
> irb(main):010:0> c.arg
> => 0.785398163397448
> irb(main):011:0> c.angle
> => 45.0

I think the error message is misleading, because

class << c
def angle;end
end

should add a singleton method to instance c
or overwrite the behavior of inherited method

as expected the behaviuor of c.angle is changed

it should not "define singleton method for Complex"

Regards, Daniel

You are correct.

What Nobu said is that you'll see a more helpful message
when it's easier to do so.
At the moment, it seems, the method is defined in your
singleton object then an exception is raised with a
misleading message. IRB traps the error and continues.

require 'complex'

c=Complex.new 1,1

begin
def c.angle
(arg/Math::PI)*180
end
rescue => e
p e
end
#<TypeError: can't define singleton method "angle" for Complex>

p c.arg #.->=> 0.785398163397448
p c.angle #.->=> 45.0

# Complex is unchanged
c2=Complex.new 1,1
p c2.arg #.->=> 0.785398163397448
p c2.angle #.->=> 0.785398163397448

daz

Hi,

At Sun, 6 Nov 2005 23:08:01 +0900,
ts wrote in [ruby-talk:164454]:

> /* Numerics should be values; singleton_methods should not be added to them */

Yes, but the problem is with irb

Not irb, the singleton_method should be denied *before*
defined. But there is no hook method before definition right
now.

···

--

Daniel Schüle wrote:

what is the advantage or typical use of having
singleton method for a class?

File.exist?('myfile')

There's no instance (File.new), yet.

File.new is another

daz

Hi --

Sean O'Halpin wrote:

irb(main):014:0* class << Complex

You're using the wrong syntax here. To re-open a class, just use
normal class definition syntax:

class Complex
def angle
arg/Math::PI*180.0
end
end

I found out that I also can use

Complex.class_eval do
def angle
arg / Math::PI * 180
end
end

this would "update" the method for all instances of Complex class

Or:

def Complex.angle
...

class << Complex
def angle; "angle"; end
end

would create singleton_method for Complex class itself
Complex.angle => "angle"

what is the advantage or typical use of having singleton method for a class?

Singleton methods of classes are generally referred to as "class
methods", and they're actually the most frequent use-case for
singleton methods. You'll find a lot of them in the core. Here are
some examples:

Regexp.escape(string)
File.open(filename)
Math.sqrt(num) # Math is actually a Module, not a Class, but same
# idea
Class.new

etc.

David

···

On Mon, 7 Nov 2005, Daniel Schüle wrote:

On 11/6/05, Daniel Schüle <uval@rz.uni-karlsruhe.de> wrote:

--
David A. Black
dblack@wobblini.net

Sean O'Halpin wrote:
> > irb(main):014:0* class << Complex

I think Daniel was, correctly, trying to limit his change
to his own object. He didn't want to affect the class.

If you read what Daniel wrote:

I would like to have the angle method
to return the angle in degrees for each
Complex instance, how can I achieve it
the obvious didn't work for me

and his subsequent message that Complex.class_eval does what he wants
I think you will see that all he really wanted to do was to redefine
the instance method for angle which is more usually done by re-opening
class as I showed.
All the singleton stuff is a bit of a red herring as far as Daniel is concerned.

I would think that most people on this list would agree that this:

class Complex
def angle
arg/Math::PI*180.0
end
end

is the usual way to do this.

Regards,

Sean

···

On 11/6/05, daz <dooby@d10.karoo.co.uk> wrote:

> On 11/6/05, Daniel Schüle wrote:

daz wrote:

Daniel Schüle wrote:

what is the advantage or typical use of having
singleton method for a class?

File.exist?('myfile')

There's no instance (File.new), yet.

File.new is another

ok, now it makes sense
thx

Sean O'Halpin wrote:

>
> Sean O'Halpin wrote:
> > > irb(main):014:0* class << Complex
>
> I think Daniel was, correctly, trying to limit his change
> to his own object. He didn't want to affect the class.

If you read what Daniel wrote:

>> [[ I have one more related question ]]

>> I would like to have the angle method
>> to return the angle in degrees for each
>> Complex instance, how can I achieve it
>> the obvious didn't work for me

and his subsequent message that Complex.class_eval does what he wants
I think you will see that all he really wanted to do was to redefine
the instance method for angle which is more usually done by re-opening
class as I showed.

Yes, I was defending Daniel's possible intentions which were
ambiguous before his follow-up message.
I see now that in his second (related) question, he *was*
wanting to affect the class and that that was the part you
were responding to.

I would think that most people on this list would agree that this:
> class Complex
> def angle
> arg/Math::PI*180.0
> end
> end

is the usual way to do this.

Now we're focused on instance methods, I think you're on safe ground

Simple misunderstanding -- no aggression intended.

Regards,

Sean

daz

···

On 11/6/05, daz wrote:
> > On 11/6/05, Daniel Schüle wrote:

Hi --

> I found out that I also can use
> > Complex.class_eval do
> def angle
> arg / Math::PI * 180
> end
> end
> > this would "update" the method for all instances of Complex class

Or:

def Complex.angle

Whoops -- wrong. That's actually a way to define the singleton method
on Complex, as discussed later in your post.

David

···

--
David A. Black
dblack@wobblini.net