2019-08-05
インスタンス変数とかはselfに依存するという話
@var
が何を指すかって、何を元に判断しているのだろうか。
前提
ローカル変数
「ローカル変数のスコープは、宣言した位置からその変数が宣言されたブロック、メソッド定義、またはクラス/モジュール定義の終りまでです。」*1
class Sample
var = 1
end
class Sample
p var # => undefined local variable or method `var'
end
インスタンス変数
インスタンス変数は特定のオブジェクトに属している。
(オブジェクトは変数やメソッドを束ねたもの、と考えてよさそう。)
class Sample
@var = 2
end
class Sample
p @var # => 2
end
本題
「定数やクラス変数、*2
サンプルコードを仕切り直して、まず下準備。
class Sample
# `Sample`というClassのインスタンスに@varをもたせる
@var = "in Sample"
def initialize
# `sample`というSampleのインスタンスに@varをもたせる
@var = "in an instance of Sample"
end
end
sample = Sample.new
class << Sample
# `Sampleの特異クラス`というClassのインスタンスに@varをもたせる
@var = "in singleton class of Sample"
end
class << sample
# `sampleの特異クラス`というClassのインスタンスに@varをもたせる
@var = "in singleton class of sample"
end
x_eval メソッドをつかって、いつどの@var が呼ばれるのかをみてみる。
(x_eval したときのコンテクストについてはこちらでまとめた。)
Sample.class_eval do
# self: Sample
# klass: Sample
p @var # => "in Sample"
end
Sample.instance_eval do
# self: Sample
# klass: Sampleの特異クラス
p @var # => "in Sample"
end
sample.instance_eval do
# self: sample
# klass: sampleの特異クラス
p @var # => "in an instance of Sample"
end
@var として呼ばれるのは、その時点で self によって指し示されるオブジェクトがもつ@var であることが分かった。
雑感
ここ数日 eval とかについて考えていたら、Ruby においてコードは一見とても立体的に見えるけれど、つまるところ起きているのは単なるプロセスたちの実行で、それをさも「オブジェクトにメッセージを送っている」とか「クラスの中にいる」とか、イリュージョンのように仕立てているだけなのだなあ…と感じた。
*1:https://docs.ruby-lang.org/ja/latest/doc/spec=2fvariables.html