5

この質問のように、定義されていないローカル変数がそれ自体の割り当て内で使用される場合、それはに評価されnilます。

x = x # => nil 

ただし、ローカル変数の名前が既存のメソッド名と競合する場合は、さらに注意が必要です。以下の最後の例が返されるのはなぜnilですか?

{}.instance_eval{a = keys} # => []
{}.instance_eval{keys = self.keys} # => []
{}.instance_eval{keys = keys} # => nil
4

3 に答える 3

13

Rubyでは、メソッドは明示的なレシーバーや括弧なしで呼び出すことができるため、ローカル変数参照とレシーバーのない引数のないメソッド呼び出しの間には構文上のあいまいさがあります。

foo

「引数なしでメソッドを呼び出す」または「ローカル変数を逆参照する」のいずれかを意味する可能性があります。fooselffoo

fooスコープ内にローカル変数が存在する場合、これは常にローカル変数の逆参照として解釈され、メソッド呼び出しとしては解釈されません。

では、ローカル変数が「スコープ内にある」とはどういう意味ですか?これは、実行時に意味的にではなく解析時構文的に決定されます。これは非常に重要です!ローカル変数は解析時に定義されます。ローカル変数への割り当てがパーサーによって認識される場合、ローカル変数はその時点からスコープ内にあります。ただし、これは実行時にのみ初期化され、実行中のコードのコンパイル時の評価はありません。

if false
  foo = 42 # from this point on, the local variable foo is in scope
end

foo # evaluates to nil, since it is declared but not initialized

ローカル変数がメソッドを「シャドウ」するのが理にかなっているのはなぜですか?メソッドがローカル変数をシャドウイングした場合、それらのローカル変数を逆参照する方法はなくなります。ただし、ローカル変数がメソッドをシャドウする場合でも、これらのメソッドを呼び出す方法があります。あいまいさは、レシーバーのない引数のないメソッド呼び出しにのみ存在します。明示的なレシーバーまたは明示的な引数リストを追加した場合でも、メソッドを呼び出すことができます。

def bar; 'Hello from method' end; public :bar

bar # => 'Hello from method'

bar = 'You will never see this' if false

bar # => nil

bar = 'Hello from local variable'

bar      # => 'Hello from local variable'
bar()    # => 'Hello from method'
self.bar # => 'Hello from method'
于 2012-10-03T12:31:33.527 に答える
1

簡単に言えば、マッツがそう定義したからです。この振る舞いは、Rubyについて私が気に入らない数少ないことの1つです。それはさらに良くなります:

a = b if a
=> nil
a
=> nil

a理論的にはa=bステートメントは実行されるべきではありませんが、変数はnilに初期化されます。

于 2012-10-03T10:37:02.993 に答える
-3

あなたの場合、それは期待されていることだからだと思います:P

1.9.3-p194 :001 > {}.instance_eval{a=1}
 => 1 
1.9.3-p194 :002 > {}.instance_eval{a}     
NameError: undefined local variable or method `a' for {}:Hash
    from (irb):2:in `block in irb_binding'
    from (irb):2:in `instance_eval'
    from (irb):2
    from /Users/rafael/.rvm/rubies/ruby-1.9.3-p194/bin/irb:16:in `<main>'

インスタンス評価はインスタンスレベルでコードを評価するため、宣言するハッシュはそれぞれ異なります。キーを返したい場合、これは機能します

1.9.3-p194 :003 > {}.instance_eval{keys = self.keys
1.9.3-p194 :004?>   keys = keys}
 => [] 
于 2012-10-03T10:40:38.407 に答える