用于类和对象的Ruby Singleton方法

时间:2011-07-20 09:31:40

标签: ruby

我正在学习Ruby Singletons,我找到了一些方法来定义和获取Class和Object单例方法的列表。

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

获取班级单身人士方法列表的方法:

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

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

对象单例方法

定义对象单例方法

的方法
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

获取对象单例方法

列表的方法
#get singleton methods list for object and it's ancestors  
obj.singleton_methods

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

还有其他方法吗?

3 个答案:

答案 0 :(得分:13)

首先,列出单例方法的方法是使用singleton_methodsmethods方法返回对象的公共和受保护方法的名称列表。此外,它在Object类中定义。试试extend实例。它是最优雅的方式之一,因为它支持代码重用,在我看来非常面向对象:

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

修改:在评论中,您询问为什么methods(false)在这种情况下不返回任何内容。阅读完C代码之后,似乎:

  • methods返回该对象可用的所有方法(也包括所包含模块中的方法)
  • singleton_methods返回对象的所有单例方法(也包括所包含模块中的方法)(documentation
  • singleton_methods(false)返回对象的所有单例方法,但在包含的模块中声明的方法
  • methods(false)假设通过调用singleton_methods返回单例方法,它还会将参数false传递给它;这是一个错误还是一个功能 - 我不知道

希望这可以澄清一下这个问题。底线:致电singleton_methods,似乎更可靠。

答案 1 :(得分:6)

更多方法:

班级单身人士方法

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

对象单例方法

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

接下来,您可以将define_methoddefine_singleton_methodsend结合使用,例如

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

及其所有可能的组合。要使用define_method,您需要首先捕获单例类(对于类对象也是如此)

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

另一种方法是在单例类对象上使用class_eval

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

然后你再次将sendclass_eval ...

结合起来

我想有无数种方法:)

答案 2 :(得分:1)

对象单例方法

instance_eval的

class A
end

a = A.new

a.instance_eval do
def v 
"asd"
end
end

 a.singleton_methods
 => [:z, :v]