2010/08/07

instance_variable

http://midorex.blogspot.com/2010/07/attraccessor.html
http://midorex.blogspot.com/2010/08/singletonclass.html
http://midorex.blogspot.com/2010/08/selfclass.html
これらに関連して...

class Test
  @x = 'x'
  class << self
    attr_accessor :x
  end
end

class Test1
  def initialize
    self.class.singleton_class.send(:attr_accessor, :x)
    self.class.x = 'x1'
  end
end

t, t1 = Test.new, Test1.new
puts "t = Test.new, t1 = Test1.new"
puts "t.class.x=> #{t.class.x}"
puts "t1.class.x=> #{t1.class.x}"
puts "t.class.instance_variables=> #{t.class.instance_variables}"
puts "t1.class.instance_variables=> #{t1.class.instance_variables}"

結果

t = Test.new, t1 = Test1.new
t.class.x=> x
t1.class.x=> x1
t.class.instance_variables=> [:@x]
t1.class.instance_variables=> [:@x]

以上をふまえて

class Test オブジェクトと
それを new した オブジェクトと
class Test の特異クラスになったオブジェクト
この3つのオブジェクトにそれぞれ @x と attr_accessor, :x を定義してみる練習

  4 class Test
  5   @x = 'x'
  6   class << self
  7     @x = 'singleton-xxx'
  8     attr_accessor :x
  9     self.class.send(:attr_reader, :x)
 10   end
 11   def initialize
 12     @x = 'ini-xyz'
 13   end
 14   attr_accessor :x
 15 end
 16
 17 t  = Test.new
 18 puts "t = Test.new"
 19 puts "t.x=> #{t.x}"
 20 puts "t.instance_variables=> #{t.instance_variables}"
 21 puts "--\n"
 22 puts "t.class.x=> #{t.class.x}"
 23 puts "t.class.instance_variables=> #{t.class.instance_variables}"
 24 puts "--\n"
 25 s = t.class.singleton_class
 26 puts "s = t.class.singleton_class"
 27 puts "s=> #{s}"
 28 puts "s.x =>#{s.x}"
 29 puts "s.instance_variables=> #{s.instance_variables}"

実行結果

t = Test.new
t.x=> ini-xyz
t.instance_variables=> [:@x]
--
t.class.x=> x
t.class.instance_variables=> [:@x]
--
s = t.class.singleton_class
s=> #<Class:Test>
s.x =>singleton-xxx
s.instance_variables=> [:@x]


line5 の @x を外から読めるようにしているのは
line8 attr_accessor :x

同様に
line7 の@x は
line9 の self.class.send(:attr_reader, :x)

line12 の@x は
line14 attr_reader :x

おもしろいことに

  4 class Test
  5   @x = 'x'
  6   class << self
  7     @x = 'singleton-xxx'
  8     attr_accessor :x
  9     # self.class.send(:attr_reader, :x)
 10   end
 11   def initialize
 12     @x = 'ini-xyz'
 13     self.class.class.send(:attr_accessor, :x)
 14   end
 15   attr_accessor :x
 16 end

line9 のかわりに line13 にしても同じ結果を得ることができた。

+++ memo +++

あたりまえだけども
class Test
attr_reader :x
def initialize
@x = 'ini-xyz'
end
end
t = Test.new
t.x
=>'ini-xyz'
こうすると class Test のインスタンスが定義したインスタンス変数に代入された値を得られる。

new した class Test のインスタンスではなくて、
class Test そのものや、class Test の特異クラスにも
それぞれインスタンス変数を定義できるしそれらのアクセサを定義できるということを
『プログラミングRuby1.9 言語編』(ISBN: 978-4-274-068096) P.351 から学ぶことができた。

# P.351 あたりをうろうろしたままぜんぜん先に進んでいない。それにしても暑い。

0 件のコメント: