Vladimir Tsukanov Vladimir Tsukanov - 7 months ago 15
Ruby Question

Ruby Singleton methods for class and objects

I am learning Ruby Singletons and i found some ways to define and get list of Class and Object singleton methods.

Class Singleton Methods



Ways to define class singleton methods:

class MyClass

def MyClass.first_sing_method
'first'
end

def self.second_sing_method
'second'
end

class << self
def third_sing_method
'third'
end
end

class << MyClass
def fourth_sing_method
'fourth'
end
end
end

def MyClass.fifth_sing_method
'fifth'
end

MyClass.define_singleton_method(:sixth_sing_method) do
'sixth'
end


Ways to get list of class singletons methods:

#get singleton methods list for class and it's ancestors
MyClass.singleton_methods

#get singleton methods list for current class only
MyClass.methods(false)


Object Singleton Methods



Ways to define object singleton methods

class MyClass
end

obj = MyClass.new

class << obj
def first_sing_method
'first'
end
end

def obj.second_sing_method
'second'
end

obj.define_singleton_method(:third_sing_method) do
'third'
end


Way to get list of object singleton methods

#get singleton methods list for object and it's ancestors
obj.singleton_methods

#get singleton methods list for current object only
obj.methods(false)


Are there other ways to do this?

Answer

First of all, the way to list singleton methods is with singleton_methods. The methods method returns a list of the names of public and protected methods of the object. Also, it is defined in the Object class. Try extending an instance. It is one of the most elegant ways, as it supports code reuse and seems to me very object-oriented:

class Foo
  def bar
    puts "Hi"
  end
end

module Bar
  def foo
    puts "Bye"
  end
end

f = Foo.new
f.bar
#=> hi

f.extend Bar
f.foo
#=> bye

f.methods(false)
#=> []
# the module we extended from is not a superclass
# therefore, this must be empty, as expected

f.singleton_methods
#=> ["foo"]
# this lists the singleton method correctly

g = Foo.new
g.foo
#=> NoMethodError

Edit: In the comment you asked why methods(false) returns nothing in this case. After reading through the C code it seems that:

  • methods returns all the methods available for the object (also the ones in included modules)
  • singleton_methods returns all the singleton methods for the object (also the ones in included modules) (documentation)
  • singleton_methods(false) returns all the singleton methods for the object, but not those declared in included modules
  • methods(false) supposedly returns the singleton methods by calling singleton_methods, but it also passes the parameter false to it; whether this is a bug or a feature - I do not know

Hopefully, this clarifies the issue a little. Bottom line: call singleton_methods, seems more reliable.