2016-08-11 12 views
0

私はクラスの外で宣言された変数がオブジェクトmainのインスタンス変数になることを理解しています。Ruby:クラスの外で@@対@変数?

機能的には、これは@@と宣言するのと異なりますか?

file2.rbで宣言されている@testがfile1.rb(requireから)にアクセスしたときに例外をスローすると予想していましたが、要求しませんでした。これは、常に1つの主要なオブジェクトがあり、@と@@はこのスコープで同等であることを意味しますか?

答えて

0

私はクラスの外で宣言された変数がオブジェクトmainのインスタンス変数になることを理解しています。

機能的には、これは@@と宣言するのと異なりますか?

はい、あります。 @はインスタンス変数、@@はクラス変数です。トップレベルでは、@メインオブジェクトのインスタンス変数であり、@@Objectのクラス変数である:

@@foo = :bar 
# warning: class variable access from toplevel 

Object.class_variables 
# => [:@@foo] 

Iが(を通じてfile1.rbにアクセスしたときに例外をスローするfile2.rbで宣言さ@testを期待していましたrequire)、それはそうではありませんでした。アクセスしたときに決してraiseExceptionが、でも、彼らは存在しませんインスタンス変数:

これは実際にあなたの質問とは何の関係もありません。その場合、彼らは単にnilと評価されます。

これははい、一つのメインオブジェクトがある唯一の主な目的が常にある

を意味しています。

そして、@@@はこの範囲で同等ですか?

いいえ、そうではありません。トップレベルの@mainのインスタンス変数であり、最上位の@@Objectのクラス変数です。クラス変数はすべてのサブクラスによって継承されるため、クラスのすべてのインスタンスとそのすべてのサブクラスとすべてのクラスはObjectのサブクラスであり、ほとんどすべてのオブジェクトはObjectの(間接的な)インスタンスです。つまり、最上位の@@ (ほぼ)グローバル変数です。

したがって、トップレベル@@@のスコープはと非常に異なるです!

0

いいえ、彼らは確かに等価ではありません。

@foo = 'bar' 
instance_variables 
# => [:@prompt, :@foo] 

@@bar = 'baz' 
# warning: class variable access from toplevel 
instance_variables 
# => [:@prompt, :@foo] 

ときrequireファイル、それはrequireラインの状況を想定しています。すなわち:

# file1.rb 
@foo = 'bar' 

# file2.rb 
puts instance_variables 

# irb 
require './file1' 
require './file2' 
# => [:@prompt, :@foo] 

main単にObjectのインスタンスです。 more about main hereを読むことができます。

+0

ありがとうございますが、これはスコープゲートではない場合、なぜrequire2を呼び出すスクリプトでfile2で宣言されたプレーン変数にアクセスできないのでしょうか? – kehtyr

+0

@kehtyrあなたが正しいです、私は間違っています。各ファイルは、メソッドスコープの境界と同様に、独自のローカルスコープ内で定義されます。しかし、それらは同じ 'main'インスタンス内にあります。 – coreyward

関連する問題