ruby self.class.class_eval或singleton_class.class_eval

Fiv*_*ell 10 ruby metaprogramming ruby-1.9

我这样做有什么不同

class T

  def initialize
   self.class.class_eval do
      def test
        return self.class.object_id
     end
   end
  end

end
Run Code Online (Sandbox Code Playgroud)

class T

  def initialize
    singleton_class.class_eval do
      def test
        return self.class.object_id
     end
   end
  end

end
Run Code Online (Sandbox Code Playgroud)

谢谢

PS.Tass回答说,在这个例子中,singleton_class将为每个新对象返回一个不同的object_id,因为singleton_class只属于一个Object.但IRB接下来会说明

1.9.2p180 :001 > class T
1.9.2p180 :002?>   
1.9.2p180 :003 >     def initialize
1.9.2p180 :004?>      singleton_class.class_eval do
1.9.2p180 :005 >               def test
1.9.2p180 :006?>                 return self.class.object_id
1.9.2p180 :007?>              end
1.9.2p180 :008?>        end
1.9.2p180 :009?>     end
1.9.2p180 :010?>   
1.9.2p180 :011 >     end
 => nil 
1.9.2p180 :012 > t = T.new
 => #<T:0x00000100ae9cb8> 
1.9.2p180 :013 > t1 = T.new
 => #<T:0x00000100ad7ef0> 
1.9.2p180 :014 > t1.test == t.test
 => true 
1.9.2p180 :015 > t1.test
 => 2153233300 
1.9.2p180 :016 > t.test
 => 2153233300 
1.9.2p180 :017 > 
Run Code Online (Sandbox Code Playgroud)

Ali*_*kau 12

这些T类的实例之间的区别在于方法查找算法:始终在单例类(及其模块)中搜索方法,并且只有在此处找不到它时,才会在类中搜索它.

这意味着如果我们在初始化之后将方法添加test到类的第一个实现中,那么T我们将得到与我们为类的第二个实现执行相同操作时不同的结果T:

# First example
class T
  def initialize
    self.class.class_eval do
      def test
        return self.class.object_id
      end
    end
  end
end

t = T.new

class T
  def test
    'overriden'
  end
end

puts t.test # => 'overriden'
Run Code Online (Sandbox Code Playgroud)
class T
  def initialize
    singleton_class.class_eval do
      def test
        return self.class.object_id
      end
    end
  end
end

t = T.new

class T
  def test
    'overriden'
  end
end

puts t.test # => 77697390
Run Code Online (Sandbox Code Playgroud)


Rea*_*onk 8

singleton_class为您Class提供该对象的独特之处.self.class为您提供该Class共享的所有对象的类.

foobar = Array.new

# this defines a method on the singleton class
def foobar.size
  "Hello World!"
end

foobar.size  # => "Hello World!"
foobar.class # => Array

bizbat = Array.new
bizbat.size  # => 0
Run Code Online (Sandbox Code Playgroud)

在上面的示例中,singleton_class将为object_id每个新对象返回不同的内容,因为a 只singleton_class属于一个Object.self.class将返回相同,因为每次self.class指向相同Class.

  • 这几乎直接来自文档.但这不是问题的答案.这两种方法在上面的代码中实际有什么不同? (2认同)