Singleton Method

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

···

--
Posted via http://www.ruby-forum.com/.

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
>> 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
>>

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 Wright

···

On Dec 21, 2007, at 6:51 PM, Ryan Lewis wrote:
         from :0

Just out of curiosity, is there a difference between

def a.second
...
end

and

class << a

?

Gary Wright wrote:

···

On Dec 21, 2007, at 6:51 PM, Ryan Lewis 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 Wright

--
Posted via http://www.ruby-forum.com/.

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 Wright wrote:

···

On Dec 21, 2007, at 6:51 PM, Ryan Lewis 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 Wright

--
Posted via http://www.ruby-forum.com/.

I think the answer is No, there isn't a difference, but it's something I've
been wondering about.
From http://blog.jayfields.com/2007/04/ruby-class-methods.html 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 21, 2007 8:24 PM, Joon You <joon@rubyhead.com> wrote:

Just out of curiosity, is there a difference between

def a.second
...
end

and

class << a

?

Gary Wright wrote:
> On Dec 21, 2007, at 6:51 PM, Ryan Lewis 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 Wright

--
Posted via http://www.ruby-forum.com/.

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 Wright

···

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

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

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 Wright

···

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).

Gary Wright wrote:

> 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

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 1:35 AM, Ryan Lewis wrote:

--
Jabber: sepp2k@jabber.org
ICQ: 205544826

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

Pat

···

On Dec 21, 2007 11:51 PM, Gary Wright <gwtmp01@mac.com> wrote:

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

> 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

No.
<snip tons of stuff>

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.

···

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

Gary Wright wrote:

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

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

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.

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.

···

On Dec 22, 2007 12:20 AM, Gary Wright <gwtmp01@mac.com> wrote:

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 Wright