Ruby Singleton methods for class and objects

后端 未结 3 388
别那么骄傲
别那么骄傲 2021-02-02 12:19

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

相关标签:
3条回答
  • 2021-02-02 12:27

    Object singleton methods

    instance_eval

    class A
    end
    
    a = A.new
    
    a.instance_eval do
    def v 
    "asd"
    end
    end
    
     a.singleton_methods
     => [:z, :v] 
    
    0 讨论(0)
  • 2021-02-02 12:33

    Some more ways:

    Class singleton methods

    class << MyClass
      define_method :sixth_sing_method do
        puts "sixth"
      end
    end
    
    class MyClass
      class << self
        define_method :fourth_sing_method do
          puts "seventh"
        end
      end
    end
    

    Object singleton methods

    class << obj
      define_method :fourth_sing_method do
        puts "fourth"
      end
    end
    

    Next, you can use define_method and define_singleton_method in combination with send, e.g.

    obj.send :define_singleton_method, :nth_sing_method, lambda{ puts "nth" }
    

    and all possible combinations thereof. To use define_method, you need to capture the singleton class first as in this (the same works for class objects, too)

    singleton_class = class << obj; self end
    singleton_class.send :define_method, :nth_sing_method, lambda{ puts "nth" }
    

    Another ways is using class_eval on the singleton class objects:

    singleton_class.class_eval do
      def nth_sing_method
        puts "nth"
      end
    end
    

    And then you once again may combine send with class_eval...

    There are myriads of ways, I guess :)

    0 讨论(0)
  • 2021-02-02 12:39

    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.

    0 讨论(0)
提交回复
热议问题