# Singleton methods without the singleton class

**URL:** <https://www.ruby-forum.com/t/singleton-methods-without-the-singleton-class/185189>\
**Category:** Ruby\
**Created:** [March 15, 2010, 7:53pm UTC](https://www.ruby-forum.com/t/singleton-methods-without-the-singleton-class/185189 "2010-03-15T19:53:48Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![headius](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/h/7c8e57/32.png) [@headius](https://www.ruby-forum.com/u/headius)\
**Post date:** [March 15, 2010, 7:53pm UTC](https://www.ruby-forum.com/t/singleton-methods-without-the-singleton-class/185189/1 "2010-03-15T19:53:48Z")

</div>

Hi all!

JRuby currently allows you to add singleton methods to normal Java  
objects like this:

foo = java.lang.String.new(‘blah’)  
def foo.bar

# do something

end

Unfortunately, this feature requires us to keep a weak table of all  
the Java objects that enter Ruby space, since we can’t attache this  
singleton method directly to the object itself. I would like to  
eliminate this feature at some point, but I recognize that since  
people are using it we need an alternative.

So I’ve hacked together a short script that provides a “Singletonizer”  
module that can simulate singleton methods without actually creating a  
new singleton class:

> <https://gist.github.com/headius/333174>

The basic idea is to go ahead and add the method to the actual class,  
but add it via a hashed lookup on a per-instance basis. Objects which  
have had the method added will have a corresponding entry in their  
attached\_methods table. Objects that don’t will raise NoMethodError as  
usual.

Thoughts? Comments? This version is obviously not threadsafe, but it  
gets you pretty close to singleton methods without requiring singleton  
classes.

- Charlie

---

<div class="post-metadata">

**Author:** ![headius](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/h/7c8e57/32.png) [@headius](https://www.ruby-forum.com/u/headius)\
**Post date:** [March 22, 2010, 3:25pm UTC](https://www.ruby-forum.com/t/singleton-methods-without-the-singleton-class/185189/2 "2010-03-22T15:25:56Z")

</div>

Charles Nutter wrote:

> Thoughts? Comments? This version is obviously not threadsafe, but it  
> gets you pretty close to singleton methods without requiring singleton  
> classes.

What if you are defining a singleton method to override a method which  
already exists in the class? It’s fixable…

module Singletonizer  
def attach\_method(name, &block)  
(@attached\_methods ||= {})[name] = block  
class\_method = “\__class_#{name}”  
return if respond\_to? class\_method  
if respond\_to? name  
self.class.class\_eval “alias :#{class\_method} :#{name}”  
else  
self.class.class\_eval \<\<-RUBY  
def #{class\_method}(\*args)  
ex = NoMethodError.new(“undefined method `#{name}’ for  
#{self.inspect}:#{self.class}”)  
ex.set\_backtrace caller(2)  
raise ex  
end  
RUBY  
end  
self.class.class\_eval \<\<-RUBY, **FILE** , **LINE**  
def #{name}(\*args)  
if (defined? @attached\_methods) && (block =  
@attached\_methods[:#{name}])  
instance\_exec(\*args, &block)  
else  
\__class_#{name}(\*args)  
end  
end  
RUBY  
end  
end

…unless someone comes along and decides to change the definition in  
the class ☹

I note that using the block syntax for defining singleton methods means  
that singleton methods can’t take a block. But that’s not an problem if  
this is just a demo of something which will take place under the hood.

---

<div class="post-metadata">

**Author:** ![headius](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/h/7c8e57/32.png) [@headius](https://www.ruby-forum.com/u/headius)\
**Post date:** [March 22, 2010, 7:44pm UTC](https://www.ruby-forum.com/t/singleton-methods-without-the-singleton-class/185189/3 "2010-03-22T19:44:49Z")

</div>

On Mar 15, 2:53 pm, Charles Oliver N. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> singleton method directly to the object itself. I would like to  
> but add it via a hashed lookup on a per-instance basis. Objects which  
> have had the method added will have a corresponding entry in their  
> attached\_methods table. Objects that don’t will raise NoMethodError as  
> usual.
> 
> Thoughts? Comments? This version is obviously not threadsafe, but it  
> gets you pretty close to singleton methods without requiring singleton  
> classes.

How do you handle #extend?

I’ve always thought it would be wise if singleton methods were added  
to an anonymous module rather then directly to the object.\* Perhaps  
taking this approach will work for JRuby. While not exactly like MRI  
it should be close enough for all practical purposes.

(\* Which is why Facets extends the #extend method to do exactly that  
if you supply it a block.)

---

<div class="post-metadata">

**Author:** ![headius](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/h/7c8e57/32.png) [@headius](https://www.ruby-forum.com/u/headius)\
**Post date:** [March 22, 2010, 11:43pm UTC](https://www.ruby-forum.com/t/singleton-methods-without-the-singleton-class/185189/4 "2010-03-22T23:43:43Z")

</div>

On Mon, Mar 22, 2010 at 9:26 AM, Brian C. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)  
wrote:

> What if you are defining a singleton method to override a method which  
> already exists in the class? It’s fixable…

The problem with this is that it then makes all callers to all  
instances of that class go through all this logic. Maybe that’s not a  
big deal?

I’ve thrown this stuff into a github project here (without your  
changes for the moment):

> **[GitHub - headius/singletonizer: A way to add singleton methods to objects...](https://github.com/headius/singletonizer)**
>
> A way to add singleton methods to objects without creating singleton objects - GitHub - headius/singletonizer: A way to add singleton methods to objects without creating singleton objects

I also added a mutex around the whole body of attach\_method and  
renamed attach\_method to “def”, so the singletonizing looks a bit more  
like normal singleton methods:

instead of

def obj.foo  
blah  
end

you do

obj.def :foo do  
blah  
end

> I note that using the block syntax for defining singleton methods means  
> that singleton methods can’t take a block. But that’s not an problem if  
> this is just a demo of something which will take place under the hood.

Yeah, I don’t know of a way to make that work using just Ruby  
features; it would be possible to do it under the covers in JRuby,  
though.

- Charlie

---

<div class="post-metadata">

**Author:** ![headius](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/h/7c8e57/32.png) [@headius](https://www.ruby-forum.com/u/headius)\
**Post date:** [March 22, 2010, 11:46pm UTC](https://www.ruby-forum.com/t/singleton-methods-without-the-singleton-class/185189/5 "2010-03-22T23:46:39Z")

</div>

On Mon, Mar 22, 2010 at 1:44 PM, Intransition [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)  
wrote:

> How do you handle #extend?

I don’t 🙂

#extend would be hard to support with this, since module methods are  
often only callable against the object themselves; in other words, if  
the module doesn’t _actually_ get inserted into the object’s class  
hierarchy, the methods won’t be invokable.

Again, this can be forced under the covers in JRuby, but not through  
any normal Ruby mechanisms I know of.

> I’ve always thought it would be wise if singleton methods were added  
> to an anonymous module rather then directly to the object.\* Perhaps  
> taking this approach will work for JRuby. While not exactly like MRI  
> it should be close enough for all practical purposes.
> 
> (\* Which is why Facets extends the #extend method to do exactly that  
> if you supply it a block.)

Yes, that’s probably wise, but #extend is mostly a deal-breaker in any  
form because it forces a singleton object to be created.

- Charlie
