类和对象的Ruby单例方法

类和对象的Ruby单例方法,ruby,Ruby,我正在学习Ruby单例,我找到了一些方法来定义和获取类和对象单例方法列表 类单例方法 定义类单例方法的方法: 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

我正在学习Ruby单例,我找到了一些方法来定义和获取类和对象单例方法列表

类单例方法 定义类单例方法的方法:

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
还有其他方法吗?还有其他方法:

类单例方法

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_方法
,您需要首先捕获singleton类,如本文所述(同样适用于类对象)

然后您可以再次将
send
class\u eval
组合使用


我想有很多种方法:)

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

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:在评论中,您询问了为什么
methods(false)
在这种情况下不返回任何内容。通读C代码后,似乎:

  • methods
    返回对象可用的所有方法(包括模块中的方法)
  • singleton_methods
    返回对象的所有singleton方法(以及包含模块中的方法)()
  • singleton\u methods(false)
    返回对象的所有singleton方法,但不返回包含模块中声明的那些方法
  • methods(false)
    假定通过调用
    singleton_methods
    返回singleton方法,但它也将参数
    false
    传递给它;这是一个bug还是一个特性-我不知道

希望这能澄清一点问题。一句话:调用
singleton\u方法
,似乎更可靠。

对象singleton方法

实例评估

class A
end

a = A.new

a.instance_eval do
def v 
"asd"
end
end

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

谢谢,功能不错,我不知道。但是为什么
methods(false)
不显示添加的方法呢?我也可以通过这种方式扩展
class
,我用
methods(false)
进行了实验,得出结论认为
method(false)
只显示自己对象的方法,而不显示祖先链中上层类的方法在之前删除的注释中,您说
methods()
实例方法()的别名。
,是真的吗?在这种情况下,
instance\u methods()
如何返回单例方法?Singleton方法和instance方法是不同的。很抱歉提出了很多问题,但为了完整起见,尽管这个问题很久以前就已经得到了回答,但我还是试图理解:您还可以使用方法class_eval和instance_eval。例如:obj.instance_eval{def hi;puts“hi”;end},或Object.class_eval{def self.foo;puts“foo”;end}(这与通过开放类进行扩展相同),或与last:Object.instance_eval{def bar;puts“bar”;end}(这将打开对象的虚拟类。尽管self与前一个相同,但它仍然处于不同的环境中!)很好的总结,应该是一个维基
singleton_class = class << obj; self end
singleton_class.send :define_method, :nth_sing_method, lambda{ puts "nth" }
singleton_class.class_eval do
  def nth_sing_method
    puts "nth"
  end
end
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
class A
end

a = A.new

a.instance_eval do
def v 
"asd"
end
end

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