Singleton Method

What’s the difference between a regular method and a singleton method?

On Dec 21, 2007, at 6:51 PM, Ryan L. wrote:

What’s the difference between a regular method and a singleton method?

From the perspective of a particular object, singleton methods are
those methods that are defined within the singleton class of
the object.

Regular methods are methods that are defined within the normal
inheritance tree of the object’s class.

Method lookup is done by first checking the singleton class of an
object and if not found there by checking the normal inheritance tree.

By default objects don’t have a singleton class. The singleton class
is created when it is referenced:

$ irb

a = [1,2,3]
=> [1, 2, 3]

a.second
NoMethodError: undefined method `second’ for [1, 2, 3]:Array
from (irb):2
from :0

class <<a
def second
self[1]
end
end
=> nil

a.second
=> 2

[4, 5, 6].second
NoMethodError: undefined method `second’ for [4, 5, 6]:Array
from (irb):9
from :0

In this example, I opened up the singleton class associated
with ‘a’ and defined a new method, second, that returns the
second element of the array. As you can see, this method
is only available to that one particular array and not to
all array’s in general.

Gary W.

Just out of curiosity, is there a difference between

def a.second

end

and

class << a

?

Gary W. wrote:

On Dec 21, 2007, at 6:51 PM, Ryan L. wrote:

What’s the difference between a regular method and a singleton method?

From the perspective of a particular object, singleton methods are
those methods that are defined within the singleton class of
the object.

Regular methods are methods that are defined within the normal
inheritance tree of the object’s class.

Method lookup is done by first checking the singleton class of an
object and if not found there by checking the normal inheritance tree.

By default objects don’t have a singleton class. The singleton class
is created when it is referenced:

$ irb

a = [1,2,3]
=> [1, 2, 3]

a.second
NoMethodError: undefined method `second’ for [1, 2, 3]:Array
from (irb):2
from :0

class <<a
def second
self[1]
end
end
=> nil

a.second
=> 2

[4, 5, 6].second
NoMethodError: undefined method `second’ for [4, 5, 6]:Array
from (irb):9
from :0

In this example, I opened up the singleton class associated
with ‘a’ and defined a new method, second, that returns the
second element of the array. As you can see, this method
is only available to that one particular array and not to
all array’s in general.

Gary W.

On Dec 21, 2007, at 9:59 PM, Ben Lipton wrote:

Now, this is talking about class methods, not singleton methods on
arbitrary
objects, but I think the idea still applies because class methods are
methods on a singleton, in this case the object Parser (which
happens to be
a Class).

I think your description is a bit misleading.

A class method is a singleton method of a class object.
A class is an instance of Class.

What I’m trying to point out is that class objects
are not ‘singletons’ in the sense of the one-and-only
instance of a particular class, which it appears to be
what you were alluding to if I’m not mistaken.
There are many instances of Class: Array, Object,
Parser, Hash, and so on.

This is yet another example where the word ‘singleton’,
as in singleton method and singleton class, can get confused
with the more generic use of singleton (which I don’t
think applies here in any case).

Gary W.

So defining the ‘second’ method like so:
def Array.second
self[1]
end

is the same is making the singleton class like below.
Class << Array
def second
self[1]
end
end

Gotcha.

Thanks for the help! =)

Gary W. wrote:

On Dec 21, 2007, at 6:51 PM, Ryan L. wrote:
In this example, I opened up the singleton class associated
with ‘a’ and defined a new method, second, that returns the
second element of the array. As you can see, this method
is only available to that one particular array and not to
all array’s in general.

Gary W.

I think the answer is No, there isn’t a difference, but it’s something
I’ve
been wondering about.
From Jay Fields' Thoughts: Ruby: Class Methods we have:

“In fact, you can define a class method various ways, but the result is
always an instance method on the singleton class.”

class Parser
def self.self_process(script)
# …
end

def Parser.parser_process(script)
# …
end

class << self
def singleton_process(script)
# …
end
end

def self.singleton
class << self; self; end
end
end

Now, this is talking about class methods, not singleton methods on
arbitrary
objects, but I think the idea still applies because class methods are
methods on a singleton, in this case the object Parser (which happens to
be
a Class). So, the second and the third examples are the ones you’re
asking
about, because inside the “class Parser … end”, self is equal to
Parser.
So, he’s doing

def Parser.parser_process(script)
end

and

class << Parser
def singleton_process(script)
end
end

just like your example.

On Dec 22, 2007, at 1:35 AM, Ryan L. wrote:

end
No. Your examples are different than mine.
In your examples you are defining a singleton method
for ‘Array’, which is an object that just happens
to be a class.

In my examples I defined a singleton method for one
particular array, not all arrays, and not the object
known as Array.

Let’s see if I can summarize things a bit:

All method definitions wind up being stored in a
module of one sort or another (which includes
classes since Class is a subclass of Module,
i.e. every class is also a module).

  1. standard modules (instances of Module)
    – the methods are called instance methods

  2. standard classes (instances of Class)
    – the methods are called instance methods

  3. singleton classes of non-class/non-module objects
    – the methods are called singleton methods

  4. singleton classes of instances of Module
    – the methods are called module methods or
    singleton methods of a (particular) module

  5. singleton classes of instances of Class
    – the methods are called class methods or
    singleton methods of a (particular) class.

Since singleton classes are also classes, you can
get an infinite regress of singleton methods of
a singleton class of a singleton class of a…
But just set that aside for the moment. Here is
what the code looks like for the cases I listed:

case 1

module Enumerable
def foo; end
end

case 2

class Array
def foo; end
end

case 3

a = Object.new
def a.foo; end

also case 3

class <<a
def foo; end
end

case 4

def Enumerable.foo
end

also case 4

module Enumerable
def self.foo
end
end

also case 4

module Enumerable
class <<self
def foo; end
end
end

still case 4

class <<Enumerable
def foo; end
end

case 5

def Array.foo
end

also case 5

class Array
def self.foo
end
end

also case 5

class Array
class <<self
def foo; end
end
end

still case 5

class <<Array
def foo; end
end

I hope that helps.

Gary W.

On Dec 21, 2007 11:51 PM, Gary W. [email protected] wrote:

  def second
     self[1]
  end

end

No.

His question is, “are these the same?” to which the answer is simply
yes.

Pat

Gary W. wrote:

  end

end

No.

Yes, actually.

Your examples are different than mine.

They are. They also don’t make much sense. But they’re still equivalent
to each other.

case 5

def Array.foo
end
[…]

still case 5

class <<Array
def foo; end
end

See? Both case 5.

On Dec 22, 2007, at 2:59 AM, Sebastian H. wrote:

     self[1]

equivalent
to each other.

I was trying to point out that they didn’t make sense relative
to the previous examples in the thread, but Sebastian is correct
to point out that they are equivalent to each other.

It turns out that those definitions for Array.second end
up returning arrays, in particular they return [1], since Array
actually has a [] method, which construct and returns a new array.
In Ryan’s code, self[1], is actually a call to Array.[], which
constructs the new array.

Array.second returns [1] in those examples, something very different
what I was showing in my examples.

Gary.

You’re right, my description is misleading, though I think I had it
correctly in my head. I’m new to Ruby and still figuring out my
terminology.
Thanks for clearing that up.