2

私はメソッド定義で遊んでいてmain、IRB でそれらを呼び出していました。

def show
 p "hi"
end
#=> nil

show
#"hi"
#=> "hi"

self.show
#"hi"
#=> "hi"

上記はよく理解されています。

それでは、別のことを試してみましょう。

def Foo
 p "hi"
end
#=> nil

Foo
#NameError: uninitialized constant Foo
        #from (irb):4
        #from C:/Ruby193/bin/irb:12:in `<main>'

上記のように呼び出しFooでエラーがスローされましたが、以下はどのようにそれを削除しますか?

self.Foo
#"hi"
#=> "hi"
4

1 に答える 1

4

Ruby では、レシーバーや引数リストなしでメソッドを呼び出すことができます。ただし、これはあいまいさがあることを意味します。「引数なしで暗黙的なレシーバーでfooメソッドを呼び出す、つまり「と同等」または「変数を逆参照する」ことを意味しますか? Ruby はあなたが何を意味しているのか分からないので、いくつかの簡単なルールがあります。fooselfself.foo()foo

ローカル変数の場合、ルールは、解析時にローカル変数であることがfoo静的に認識されていない限り、常にメソッド呼び出しです。では、変数であることが静的に認識されるのはいつでしょうか? 使用前に解析された (ただし、必ずしも実行されるとは限りません!)変数への代入があった場合。foo

例:

foo        # method call

if false
  foo = 42 # will never be executed, but *will* be parsed
end

foo        # variable dereference, since the `foo` assignment was parsed

定数変数の場合、ルールはさらに単純ですFoo常に定数逆参照として解釈されます。限目。

では、そのような名前のメソッドをどのように呼び出すのでしょうか? 簡単: 私が言ったように、あいまいさは、引数リストも明示的なレシーバーもないメソッド呼び出しでのみ発生します。したがって、これらのいずれかまたは両方を追加すると、Ruby は、変数を逆参照せずにメソッドを呼び出そうとしていることを認識します。

foo()
self.foo
self.foo()

Foo()
self.Foo
self.Foo()

もちろん、上記の例では、最初のものだけが機能します。最上位でメソッドを定義すると、メソッドとして に追加されます。メソッドprivateは、レシーバが であっても、明示的なレシーバなしでのみ呼び出すことができます。プライベートなので、うまくいきません。(便利な理由から、トップレベルのメソッドが である IRb を除きます。)Objectprivateselfself.FooFoopublic

于 2013-03-07T13:05:54.660 に答える