Rubyのお勉強をしていてメソッド定義内でメソッド定義したら不思議な挙動 (JS脳には予想外だっった) だったのでメモ。
メソッド定義 (def式) 内に メソッド定義 (def式) をした場合
def a puts 'A' def b puts 'B' end print "self.b > " self.b end a # => "A" # => "self.b > B" b # => "B"
えっ? def a
内で定義した def b
が def a
の外からでも呼び出せるの…!?
JS脳的には下記のようなイメージだったのでびっくりしました
function a() { console.log('a') function b () { console.log('b') } b() } a() // a // b b() // Error: Uncaught ReferenceError: b is not defined
Ruby のメソッド定義 (def式) は呼び出されるとトップレベルに定義される?
Ruby では def式 の書かれている場所を通れば、そのファイル?のトップレベルにメソッドが定義されるのかなという印象を持ちました。
def a puts 'A' def b puts 'B' end end a # => "A" b # => "B"
a
を呼び出してないと b
は未定義になる
def a puts 'A' def b puts 'B' end end b # => undefined local variable or method `b` for main:Object
Ruby は関数ではなくメソッドで、レシーバー.関数名 引数
の形で呼び出されるとあったので、def式で定義すると、そのファイルのトップレベルのオブジェクトがレシーバーになるからトップレベルから呼び出せるのかな〜?とか考えていました。詳しくはないので完全に憶測なのですが…
メソッド定義 (def式) は後から呼び出されたもので上書きされる?
先の実験でメソッド定義内にあるメソッド定義は外側のメソッドを呼び出した際に定義されることがわかりました。
という事は同じ名前のメソッドが外側にもある場合、メソッドの呼び出し順によって、呼び出されるメソッド上書きされが変わってしまう可能性があるのではないかと思い試してみました。
def a puts 'A' b def b puts 'B inside A' end b end def b puts 'B' end b # => "B" … トップレベルのメソッドが呼び出される a # => "A" # => "B" … メソッド内の def b の定義を通る前なので、外側のトップレベルのメソッドが呼び出されている # => "B inside A" … a 内の b メソッドが定義され、新しく定義された b が呼び出されている b # => "B inside A" # トップレベルの b メソッドは a 内で定義された方に上書きされてしまっている
予想通りでした。
Ruby の場合同じファイル内でメソッド定義する場合はメソッド名が重複しないように気をつける必要がありそうです。
そもそもトップレベルにつらつら定義するのが Ruby 的お作法では良くないのかも? この辺りの文化については詳しくないのでどこで学べば良いのでしょう…?
ポエム
Ruby のメソッド定義内でメソッド定義したらメソッド外で呼び出したらエラーになるよね〜って思って実行したらふつーに呼び出せてしまってびっくりしました。慣れ親しんでる JavaScript の関数定義と違ってRuby の メソッドて定義 (def式) は常にトップレベルに定義されるって感じっぽいのですね。JavaScript感覚で使ってるとハマりそうでした。
Ruby は関数じゃなくてメソッドって呼ぶのなんでだろう?慣習???みたいに思ってたのですが、今回のハマりで読んでたRubyの本に
レシーバーに含まれる情報を使用しないメソッドを関数的メソッドと呼ぶ。全てのメソッドはレシーバー情報を持っているので純粋な関数ではない
初めてのRuby 著 Yugui
みたいな感じに書かれていて、オブジェクトに紐付いてて呼び出し元(レシーバー)の情報を持っているとメソッド?
トップレベルに置かれた def式 は mail オブジェクトとかに紐付いててその情報持ってるってこと??
って事は JavaScript はブラウザで実行したらfunction
も全部 window
オブジェクトに紐づいて window.func()
で呼び出せるから関数じゃなくて本当はメソッドなん???
むむむ?????
と解ったよーな、解らんよーな感じになりました。
ナルホドわからん!! 俺は雰囲気でぷろぐらむを描いている!!!!
- 作者: Yugui
- 出版社/メーカー: オライリージャパン
- 発売日: 2008/06/26
- メディア: 大型本
- 購入: 27人 クリック: 644回
- この商品を含むブログ (251件) を見る
- 作者: まつもとゆきひろ,David Flanagan,卜部昌平(監訳),長尾高弘
- 出版社/メーカー: オライリージャパン
- 発売日: 2009/01/26
- メディア: 大型本
- 購入: 21人 クリック: 356回
- この商品を含むブログ (129件) を見る