From: "takeru sasaki" <sasaki.takeru / gmail.com> Subject: [ruby-list:45298] グローバルにdefしたメソッドのスコープ Date: Wed, 6 Aug 2008 19:25:34 +0900 るびきちです。 とりあえず、xmpfilterによる注釈形式で途中の値を確かめましょう。 class Foo def bar(a,b) "Foo#bar(#{a},#{b})" end def baz hello(3,4) # => "Foo#bar(3,4)" Poo.hello(7,8) # => "Poo.bar(7,8)" end end def bar(e,f) "global bar(#{e},#{f})" end def hello(c,d) # globalのbarではなくFoo#barが呼ばれる # Object#helloは二度呼ばれているので「=> 1回目の値, 2回目の値」と注釈されている self # => #<Foo:0x82da890>, main bar(c,d) # => "Foo#bar(3,4)", "global bar(1,2)" end class Poo def self.bar(i,j) "Poo.bar(#{i},#{j})" end def self.hello(g,h) # Poo.barが呼ばれる bar(g,h) # => "Poo.bar(7,8)" end end f2 = Foo.new f2.baz # => "Poo.bar(7,8)" hello(1,2) # => "global bar(1,2)" method(:hello) # => #<Method: Object#hello> method(:bar) # => #<Method: Object#bar> > 下記プログラムを実行したときの「globalのbarではなくFoo#barが呼ばれる」部分はなぜそうなるのでしょうか。 > 直感的には「globalのbar」が呼ばれそうに思います。 グローバル関数は、実はObjectクラスのプライベートなインスタンスメソッドです。 つまり class Object private def bar(e,f) "global bar(#{e},#{f})" end def hello(c,d) bar(c,d) end end と同じです。 prviateになっているのは、関数的メソッド呼び出ししか許さないようにするためです。 だからどう見ても関数です。 しかし、Foo#baz内でhelloを呼ぶと、Foo#helloが定義されていないので、 グローバル関数のObject#helloを呼びます。注釈にあるように、Object#hello内での selfはFooオブジェクトなのでObject#hello内でbarを呼び出すと、まずFoo#barを 探します。定義されていたので、Foo#barが呼び出されました。 ポイントは、グローバル関数はクラスに属するメソッドであることです。 -- rubikitch Blog: http://d.hatena.ne.jp/rubikitch/ Site: http://www.rubyist.net/~rubikitch/