自インスタンスのインスタンスメソッドを呼び出す時の、selfの使い方がよくわからないんです
class Sample attr_accessor :abc def xyz;@xyz;end def xyz=(v);@xyz=v;end def asdf=(v); p "in asdf with #{v}";end def set abc = 'def' xyz = 'uvw' asdf = 'axvaf' end def print p abc p xyz end def set2 self.abc = 'def2' self.xyz = 'uvw2' self.asdf = 'qwer' end def print2 p self.abc p self.xyz end end o = Sample.new o.set # => 何も出力されない p o # => #<Sample:0x1f72308> o.set2 # => "in asdf with qwer" p o # => #<Sample:0x1f72308 @abc="def2", @xyz="uvw2"> o.print # => "def2", "uvw2" o.print2 # => "def2", "uvw2"
なんでや。。なんでself.
を書いていないset
ではアクセサが呼ばれないんや。。
方々ぐぐっても納得いく説明が見つからない。どの説明でも、このset
の書き方では「メソッド呼び出しではなくローカル変数への代入になるんだよ」と書いてあるだけで、なんでそういう解釈になるのかがよくわからない。
一方でprint
の方はself.
がなくてもアクセサメソッド呼び出しになっている訳じゃないですか。rubyはそういうものということですかね。。
ぐぐったメモ
しかし自分自身のメソッドを呼ぶのに「自分の」とわざわざ指定しなければな らないのは面倒だ。それでselfに対する呼び出しのときはメソッドを呼び出す 対象のオブジェクト(レシーバreceiver)を省略できるようになっている。
→でもset
で省略できてないじゃないですか。。
Why does attr_accessor in module require 'self.'? - Ruby Forum
ruby's parser sees "a = ..." and assumes that "a" is local variable, rather than attempting to call #a= (the writer method). This has the advantage that, since local variables always "shadow" methods of the same name, you can write code with the confidence that you are not invoking some method defined in the class (or somewhere up the ancestor chain) that you hadn't noticed. For one thing, this makes it easier to write code that knows as little as possible about its context, and hence can be shared around by Module#include or even copy-n-paste.
→「先にローカル変数と解釈される方が、知らんうちに意図しないメソッドを呼んだことになるよりよくない?」みたいな。インスタンス変数を変えてしまうsetterに限ってはそうかもしれない。buf = 'abc'
と何の気なしに書いたら実はmixinしたやつにbufってプロパティがあってそっちが変更されてしまっていた、とかなったりすると目も当てられない。
class Foo attr_accessor :x def bar # If this were the same as self.x = 2, or @x = 2, # it would not be possible to have a local variable 'x'? x = 2 end end
→「x = 2
で#x=()を呼び出したことになるんなら、ローカル変数xってどうやっても使えなくならね?」みたいな。メソッド名に=
が付くもの限定ルールかな。
違った。思い違いしていた。
「attr_accessor
で一括定義したアクセサメソッドなんだから、selfを省略してp abc
って書けるならabc = 'vvv'
って書けなきゃおかしくない?」って思ってた。。
abc = 'def'
これはよくある代入式の書き方。
で、obj.a = 1
はobj.a=(1)
のシンタックスシュガーなので、attr_accessor :a
などで定義させたアクセサメソッドa=()
を呼び出したかったら、self.a=(1)
とかself.a = 1
とか書いてやるのがメソッドの呼び出し方として普通。
そこで私みたいな不勉強者が調子に乗ってselfを省略してa = 1
と書くと、rubyとしてはselfを省略したメソッド呼び出しなのか代入式なのか見分けが付かなくなってしまう。そしたら代入式と解釈しておいた方が余計な副作用も起きないしいいよね、ってことでしょうかね。
これでいいですかね。。(;^ω^)ほひー
参考: 第8章 Ruby言語の詳細