Rubyのattr_accessorに関する質問です。

当方Rubyの勉強を始めたばかりなのですが、
あるホームページに掲載されていたrubyのサンプルコードを見ていると
def fuga(x)
$system.foo = [] if $system.foo == nil
end
という部分がありました。
『.の後に続く部分はメソッド名である』ということを思い出し、fooというメソッドの定義を調べてみようとfooで全体検索をかけてみたのですが、def fooという部分が見つからず
その代わりに
attr_accessor :foo
という部分が見つかりました。
それでattr_accessorという命令について調べてみた所、このattr_accessorがfooの定義をしているのだということが分かりました。しかし、このattr_accessorは最初の$system.foo = [] if $system.foo == nilという部分よりも何行か後に書かれていました。

メソッドの定義というものはそのメソッドを使うよりも前にしておかなければエラーになると思っていたのですが、この場合何故エラーにならないのでしょうか?

回答の条件
  • 1人50回まで
  • 登録:
  • 終了:2015/11/30 19:22:51

ベストアンサー

id:sheile No.1

回答回数45ベストアンサー獲得回数16

メソッドの定義というものはそのメソッドを使うよりも前にしておかなければエラーになる

はい、これは正しいです。
しかし、def fugaを定義した時点ではfugaというメソッドを定義しただけで、中のコードは評価されません。
そのため、System#fooメソッドが使われるタイミングというのはfugaを呼び出した時点になります。
ログに各タイミング書き出しながら実行すると分かりやすいかと思います。

sample.rb

puts '-- 1'

def fuga(x)
  puts '-- #fuga'
  $system.foo = [] if $system.foo == nil
end

puts '-- 2'

class System
  puts '-- System.attr_accessor'
  attr_accessor :foo
end

puts '-- 3'

$system = System.new
fuga(42)

puts '-- 4'

これを実行すると、以下の順でログが表示され、fugaでfooを使用するよりも早くattr_accessorが呼ばれていることが分かります。

-- 1
-- 2
-- System.attr_accessor
-- 3
-- #fuga
-- 4
id:tainaikappa

ありがとうございます!定義しただけでは評価されるわけではないのですね。丁寧に教えて頂けて、とてもよく理解できました。

2015/11/30 19:22:45

コメントはまだありません

この質問への反応(ブックマークコメント)

「あの人に答えてほしい」「この質問はあの人が答えられそう」というときに、回答リクエストを送ってみてましょう。

これ以上回答リクエストを送信することはできません。制限について

回答リクエストを送信したユーザーはいません