2013-02-23 6 views
5

私はRubyとPythonを同時に学習しています。私が気づいたことの1つは、これらの2つの言語がスコープを異なるように扱うように見えるということです。ここで私が何を意味するかの例です:RubyとPythonのスコープ

# Python 
a = 5 
def myfunc(): 
    print a 

myfunc() # => Successfully prints 5 

# Ruby 
a = 5 
def myfunc 
    puts a 
end 

myfunC# => Throws a "NameError: undefined local variable or method `a' for main:Object" 

デフブロックはPythonでその直接の範囲の外ではなくRubyで宣言された変数にアクセスすることができるように思われます。誰かが私の理解が正しいかどうかを確認できますか?もしそうなら、これらのスコープの考え方の1つがプログラミングでより一般的であるかどうか?

+0

Python側にとっては、あなたが正しいです(明らかにスコープが増えていますが、フレーズはそれに矛盾しません)。 – delnan

+0

可能なPythonの答えはこちら:http://stackoverflow.com/questions/370357/python-variable-scope-question –

答えて

4

免責事項:私はモジュールで定義された変数は、デフォルトでは、あるモジュール変数とそのモジュールに、このようなグローバルとおりで、Pythonで何のpythonの専門家

だん。 Rubyでは、小文字の変数を定義すると、常にローカル変数になります。ローカル変数は、変数を定義したブロックと、変数をラップするブロックに定義されているprocs/lambdasでのみアクセスできます。変数がスコープを横断するためのRubyで

が、それはどちらかである必要がある:

  • 定数(ALL_CAPS):常にアクセス可能で、右の範囲が付いている場合
  • クラス変数(@@double_at):定義クラスとサブクラスから常にアクセス可能ですが、外部からはアクセスできません
  • インスタンス変数(@single_at):そのオブジェクト内からのみアクセス可能で、getterメソッドでは外部からアクセス可能/ get_instance_variable
  • グローバル($starts_with_dollar):悪い考えです。すべてのスコープを通過しますが、スコープは必要ありません。使ってはいけません!
+0

ああ、Pythonでは、クラスやブロックの外に変数を定義すると、デフォルトではグローバルスコープになります。これは、RubyがRubyとは対照的に、Rubyは各スコープを別個のエンティティとして扱い、$を使用してすべてのスコープ内でアクセス可能なグローバル変数を定義します。それは正確な要約ですか? – wmock

+0

@ウィルソンモック:かなり。 – Linuxios

+2

マイナーニックピット:定数はALL_CAPSではなく、大文字で始まります。クラス名は定数です。 – steenslag

1

Rubyでは、呼び出すメソッドの外で定義された変数にアクセスする場合は、グローバルとして定義する必要があります。 Rubyはローカルスコープで定義された変数と一致するかどうか試します。見つからない場合は例外をスローします。

グローバル変数を$という符号で定義することができます。

$a = 5 
def myfunc 
    puts $a 
end 

myfunc 

ただし、一般的なルールとしてグローバル変数を定義するのは適切ではありません。そうしないと、グローバル名前空間を汚染する危険があります。

+3

これは間違っています。インスタンス変数( '@ a')で十分です。 – steenslag

1

disモジュールを使用して、Pythonが何をしているかを確認できます。

import dis 

a = 5 
def myfunc(): 
    print a 

結果:

>>> dis.dis(myfunc) 
15   0 LOAD_GLOBAL    0 (a) 
       3 PRINT_ITEM   
       4 PRINT_NEWLINE  
       5 LOAD_CONST    0 (None) 
       8 RETURN_VALUE 

ですから、aがグローバルスコープにあることがわかります。