2010/08/01

singleton_class

昨日のその後

% ruby192 -v
ruby 1.9.2dev (2010-07-11 revision 28618) [x86_64-darwin10.4.0]

module My
  def self.detail(s)
    p s
    puts "ParentName: #{s.class.name}"
    puts "Object_id: #{s.object_id}"
    puts "Methods 1to5: #{s.methods[0..4]}"
    begin
      puts "Method_define? Hello: #{s.class.method_defined?(:hello)}"
      puts "Class.Ancestors: #{s.ancestors}"
      puts "Superclass: #{s.superclass}"
      puts "Singleton_class #{s.singleton_class}"
      puts "Singleton_class #{s.singleton_class.object_id}"
    rescue
    end
    puts "\n"
  end
end
class Test1
  @@top = self
  puts "# -- main of class Test1 --"
  My::detail(self)
  class << self
    @@top_self = self
    puts "# -- class << self of class Test1 --"
    My::detail(self)
  end
  def initialize
    puts "# -- def initialize of class Test1 --"
    My::detail(self)
    puts "="*10
    puts "# TEST: @@top.singleton_class.equal?(@@top_self)"
    p @@top.singleton_class.equal?(@@top_self)
    puts "#"*5
    puts "self.class:: #{own1 = self.class}"
    puts "self.class.singleton_class::  #{own2 = self.class.singleton_class}"
    puts "# TEST: @@top.equal?(self.class)"
    p @@top.equal?(own1)
    puts "# TEST: @@top_self.equal?(self.class.singleton_class)"
    p @@top_self.equal?(own2)
  end
  def hello
    return self
  end
end
t = Test1.new.hello


実行結果

# -- main of class Test1 --
Test1
ParentName: Class
Object_id: 2151885720
Methods 1to5: [:allocate, :new, :superclass, :freeze, :===]
Method_define? Hello: false
Class.Ancestors: [Test1, Object, Kernel, BasicObject]
Superclass: Object
Singleton_class #<Class:Test1>
Singleton_class 2151885700

# -- class << self of class Test1 --
#<Class:Test1>
ParentName: Class
Object_id: 2151885700
Methods 1to5: [:nesting, :constants, :allocate, :new, :superclass]
Method_define? Hello: false
Class.Ancestors: [Class, Module, Object, Kernel, BasicObject]
Superclass: #<Class:Object>
Singleton_class #<Class:#<Class:Test1>>
Singleton_class 2151884980

# -- def initialize of class Test1 --
#<Test1:0x00000100864970>
ParentName: Test1
Object_id: 2151883960
Methods 1to5: [:hello, :nil?, :===, :=~, :!~]
Method_define? Hello: true

==========
# TEST: @@top.singleton_class.equal?(@@top_self)
true
#####
self.class:: Test1
self.class.singleton_class::  #<Class:Test1>
# TEST: @@top.equal?(self.class)
true
# TEST: @@top_self.equal?(self.class.singleton_class)
true


# TEST: @@top.singleton_class.equal?(@@top_self)
は一体何をやっているのか?

Test1 直下における self が .singleton_class メソッドを呼び出すと
#<Class:Test1>
が得られる。
その #<Class:Test1> は、class << self した self 自身と同等のオブジェクトだろうか?
これを確かめたかった。

結果は ture だった
実際

# -- main of class Test1 --
...略

Singleton_class #<Class:Test1>
Singleton_class 2151885700

# -- class << self of class Test1 --
#<Class:Test1>
ParentName: Class
Object_id: 2151885700

同じobject_id をさしている。

一方
initialize の中から呼び出した
self.class と
self.class.singleton_class
に関しても 同様に true がかえってきた。

# TEST: @@top.equal?(self.class)
true
# TEST: @@top_self.equal?(self.class.singleton_class)
true


# TEST: detail(self.class) in initialize もこの(true)結果を裏付けた。

own1 に代入された self.class はTest1 である。
それは class Test1 直下の self と同等。その証拠に同じobject_id を指している。
own2 に代入された self.class.singleton_class は、#<Class:Test1>である。
それは class << self 内の self と同等。同じobject_id を指している。

あらためて...
Test1.new して出来上がったオブジェクトは、class Test1 自身 のインスタンスだってことを思い知らされた。
class Test1 直下のself と、Test1.new されインスタンスとして登場した self とはそれぞれ異なるオブジェクト。
その証拠に異なる object_id を持つ。

class Test1
class << self
end
end

この時点で2つのオブジェクト(Test1 と #<Class:Test1>)にアクセスできる準備ができており
Test1.new することでインスタンスが生成されて3つめのオブジェクトができあがる、と。

0 件のコメント: