BigDecimal singletons

D

Dave Birch

Hi,

I'm a ruby nuby and I'm confused about something. When I try to create
a singleton method for a BigDecimal like so:

require 'bigdecimal'
d = BigDecimal.new('10')

class << d
def value
32
end
end

p.value

I get an error:
singtest.rb:7:in `singleton_method_added': can't define singleton method
"value" for BigDecimal (TypeError)

Doing this through IRB, I was surprised that if I then ran...

d.singleton_methods.sort

...after getting the error above, I get "value" listed as a singleton
method, and indeed, d.value yields 32.

If I wrap the singleton method definition in a begin...rescue block, the
TypeError is caught and not displayed, and the singleton method is
accessible.

If I replace d = BigDecimal.new('10') with d = String.new('10'), but
leave the rest of the code the same, I don't get the error and the
singleton method works as expected. Is there something simple I'm
missing?

Thanks in advance...

Dave
 
R

Rick DeNatale

Hi,

I'm a ruby nuby and I'm confused about something. =A0When I try to create
a singleton method for a BigDecimal like so:

require 'bigdecimal'
d =3D BigDecimal.new('10')

class << d
=A0def value
=A0 =A032
=A0end
end

p.value

I get an error:
singtest.rb:7:in `singleton_method_added': can't define singleton method
"value" for BigDecimal (TypeError)

Doing this through IRB, I was surprised that if I then ran...

d.singleton_methods.sort

...after getting the error above, I get "value" listed as a singleton
method, and indeed, d.value yields 32.

If I wrap the singleton method definition in a begin...rescue block, the
TypeError is caught and not displayed, and the singleton method is
accessible.

If I replace d =3D BigDecimal.new('10') with d =3D String.new('10'), but
leave the rest of the code the same, I don't get the error and the
singleton method works as expected. =A0Is there something simple I'm
missing?

The Numeric class overrides singleton_method_added to raise an error

$ ri -T Object#singleton_method_added
------------------------------------------ Object#singleton_method_added
singleton_method_added(symbol)

From Ruby 1.8
------------------------------------------------------------------------
Invoked as a callback whenever a singleton method is added to the
receiver.

module Chatty
def Chatty.singleton_method_added(id)
puts "Adding #{id.id2name}"
end
def self.one() end
def two() end
def Chatty.three() end
end

_produces:_

Adding singleton_method_added
Adding one
Adding three

$ ri -T Numeric#singleton_method_added
----------------------------------------- Numeric#singleton_method_added
singleton_method_added(p1)

From Ruby 1.8
------------------------------------------------------------------------
Trap attempts to add methods to +Numeric+ objects. Always raises a
+TypeError+

I guess this is to avoid surprises since certain kinds of numerics
can't have singleton methods (e.g. Fixnums which because of their
implementation don't have a klass pointer so can't acquire a singleton
class). So it wouldn't make sense to be able to add a singleton
method to 100 factorial (a Bignum), but not to 100 (a Fixnum).

However, the singleton_method_added callback happens after the method
has been added so it's kind of like locking the barn door after the
horse has left.

--=20
Rick DeNatale

Blog: http://talklikeaduck.denhaven2.com/
Twitter: http://twitter.com/RickDeNatale
WWR: http://www.workingwithrails.com/person/9021-rick-denatale
LinkedIn: http://www.linkedin.com/in/rickdenatale
 

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

Similar Threads


Members online

Forum statistics

Threads
473,994
Messages
2,570,223
Members
46,813
Latest member
lawrwtwinkle111

Latest Threads

Top