「それらが変数である場合」と「スコープ」の質問に対処するには、偶像破壊的に聞こえるとしても、アクセサーシンボルはインスタンス変数とは何の関係もないと答える方が簡単だったでしょう。それらはインスタンス変数を指していません。アクセサーは、getter メソッドと setterメソッドのみを定義します。Object#instance_variables の下で、Pickaxe(*) は次のように述べています。アクセサを定義するだけでは、対応するインスタンス変数が作成されないことに注意してください。
Ruby では、値を代入するまで変数は存在しません。次のコードはこれを示しています。
class MyClass
attr_accessor :name
attr_reader :book
end
obj = MyClass.new # line 6
print '1) obj.instance_variables : '; p obj.instance_variables
print '2) obj.name : '; p obj.name
obj.name = 'xyz'
print '3) obj.instance_variables : '; p obj.instance_variables
print '4) obj.name : '; p obj.name
print '5) obj.book : '; p obj.book
class MyClass
def initialize(p_book)
@book = p_book
end
end
obj = MyClass.new('The Pickaxe') # line 21
print '6) [new] obj.book : '; p obj.book
class MyClass
method_name = 'title'
attr_accessor method_name # line 26
end
obj.title = 'Programming Ruby'
print '7) obj.instance_variables : '; p obj.instance_variables
print '8) obj.title : '; p obj.title
出力:
$ ruby -w t.rb
1) obj.instance_variables : []
2) obj.name : nil
3) obj.instance_variables : ["@name"]
4) obj.name : "xyz"
5) obj.book : nil
6) [new] obj.book : "The Pickaxe"
7) obj.instance_variables : ["@title", "@book"]
8) obj.title : "Programming Ruby"
1) 空の配列: アクセサーはインスタンス変数を定義していません
2) インスタンス変数 @name を要求すると nil が返されます: 存在しません
3) 値を割り当てるとインスタンス変数が作成されました。は、セッターをパラメーター付きの通常のメソッドとして使用するための構文糖衣であることに
注意してください:
4) ゲッター メソッドは @name の値に応答します
5)インスタンス変数 @book が存在しないため、ゲッター メソッドは nil に応答します。アクセサーを定義しても、対応
するインスタンス変数が定義されていません。name =
obj.name=('xyz')
name
book
attr_reader :book
book
initialize
new
@book = p_book
26 行目) 私は常に、アクセサーはシンボルのみを受け入れると信じてきました。変数は可能ですが、関心は限られていることがわかりました。
7) setter メソッドtitle=
が @title を作成しました。これは、インスタンス変数が単一のオブジェクトに属していることも示しています。他の言語と同様に、それらはクラスのすべてのインスタンスに属しているとしばしば信じています。この場合、@name は 6 行目で作成されたオブジェクトのみに属します。
8) getter メソッドtitle
は @title の値に応答します。
class MyClass
def title # line 34
@book + ' (cheating !)'
end
end
print '9) obj.title : '; p obj.title
出力:
t.rb:34: warning: method redefined; discarding old title
9) obj.title : "The Pickaxe (cheating !)"
9) もちろん、アクセサ シンボルと対応するインスタンス変数の間には密接な相関関係があります。なぜなら、Ruby はバックグラウンドで、同じ名前のインスタンス変数を参照するメソッドを作成するからです。独自のゲッターとチートを定義できます。
クラス変数 (@@var、グローバル変数と同じくらい醜いものを嫌う人もいます) に加えて、クラスはインスタンス変数を持つこともできます。私はそれらをクラスインスタンス変数と呼びます:)。
class MyClass
: Ruby はクラス Class の新しいインスタンスを割り当て、定数 MyClass を定義し、新しいインスタンスをその定数に割り当てます。したがって、MyClass は通常のオブジェクト (Class のインスタンス) であり、インスタンス変数を持つことができます。
if RUBY_VERSION[0..2] == '1.8'
class Object
def singleton_class
class << self
self
end
end
end
end
class MyClass
singleton_class.instance_eval do
attr_accessor :counter
end
@counter = 0
def initialize(p_book)
@book = p_book
self.class.counter += 1
end
end
print '10) MyClass.singleton_methods : '; p MyClass.singleton_methods
print '11) MyClass.instance_variables : '; p MyClass.instance_variables
obj = MyClass.new('Ruby')
print '12) [new] obj.book ', MyClass.counter, ': '; p obj.book
obj = MyClass.new('Metaprogramming')
print '13) [new] obj.book ', MyClass.counter, ': '; p obj.book
出力:
t.rb:55: warning: method redefined; discarding old initialize
10) MyClass.singleton_methods : ["counter", "counter="]
11) MyClass.instance_variables : ["@counter"]
12) [new] obj.book 1: "Ruby"
13) [new] obj.book 2: "Metaprogramming"
ここでシングルトンメソッドの詳細: def `self.function` name とはどういう意味ですか?
(*) http://pragprog.com/book/ruby3/programming-ruby-1-9