2016-01-26 10 views
6

ルビは一定のアクセシビリティに関して数回の変更を受けたようです。 Ruby 1.9.2については、質問と回答hereに定数アクセシビリティに関する記述がありますが、そこに書かれている内容はもう真実ではありません。ルビー2.3定数のアクセシビリティはどのようにして決まりますか?

、私はクラスで定義された定数がある場合:

class A 
    Foo = :a 
end 

を私はinstance_eval又はclass_evalを介してアクセスすることができない。

A.new.instance_eval{Foo} # => error 
A.class_eval{Foo} # => error 
A.instance_eval{Foo} # => error 

Iクラス本体からアクセスすることができるが:

class A; Foo end # => :a 

Ruby 2.3の定数アクセシビリティはどのように機能しますか?可能であれば、Rubyにおける定数アクセシビリティの歴史的変化とそれらにつながった議論について説明してください。

+2

また、A.const_get:Foo#=>:a'と 'A.class_eval" Foo " =>:a'(2.3)です。 –

+0

@CarySwoveland権利。しかし、それらは文字列/シンボルから解析する 'eval'変種の実用的/中核的使用によく似ています。特に、 'const_get'はそれを行うために正確に設計されています。もしそれがうまくいかなければ、それは大きな問題になるでしょう。 – sawa

+1

私はこの問題をルビパーサーに対処しています。定数ルックアップではありません。 BTW 2.1は2.3のように動作します。とにかく: 'A.instance_eval {| a | aインスタンスはFooのインスタンスであり、AインスタンスはFooのインスタンスである。後者の2つは同じように動作する必要があります。そのためパーサを責めます。 – mudasobwa

答えて

2

定ルックアップは現在のスコープを横断し、モジュールを含むlexical scopeを使用しています。検索パスはModule.nesting

> module Out 
> module In 
>  puts Module.nesting 
> end 
> end 
Out::In # gets searched for a given constant first 
Out 

経由で閲覧することができ、ルックアップでもclass_evalのため、閉鎖動作を可能にするために、ブロック内に同じまま。

しかし、Ruby 1.9の中で、受信機はinstance_evalinstance_execclass_eval、およびclass_execのために、すべての定数の参照が最初の受信者の範囲内でルックアップされるだろう意味ルックアップパス、前に付加されました。

イェフダカッツは、重大な破損を理由issueを提起:

はRSpecの場合を考えてみましょう:

describe "Date" do 
    it "equals itself" do 
    Date.today.should == Date.today 
    end 
end 

我々は最初の動的スコープを使用する場合はRSpecのは、仕様を追加した場合::日、そして、それは意志 突然この仕様を破ります。レキシカルスコープはより直感的で、今日の多くの通常の使用によって期待される です。

その後、動作は、revertedに戻って1.8に戻りました。

2

注:答えはルビー2.2に基づいているの下に、Module#class_eval

の文書を1として2.3

に検証されていない、MODの文脈における文字列またはブロックを評価しますことを除いて ブロックが与えられたとき、定数/クラス変数検索は影響を受けません。

コードの下に文字列がeval編された作品以下、

A.class_eval{Foo} # uninitialized constant Foo (NameError) 

をエラーが発生したけれども。

A.class_eval("Foo") #=> :a 

また、それが適切に評価されるために定数がモジュール名またはクラス名を必要としているようです。以下は動作します:だから

A.class_eval{self::Foo} #=> :a 

、これらのん:Rubyで

A.new.instance_eval {self.class::Foo} #=> :a 
A.instance_eval {self::Foo} #=> :a 
関連する問題