From: Masahiro Utsumi Date: 2017-12-30T11:29:12+01:00 Subject: [ruby-list:50637] Re: instance_evalで定数が見えない 内海@ベルギーです instance_eval はインスタンスの挙動を変更するものと考えています。 クラス定義を間違って変えてしまわないように、見る必要のないものは 見えないほうが良いと思います。 class ClassA CONST="Hello" @@class_var = "A" def self.name @@class_var end def hi0 puts "#{CONST} I am #{self.class.name}" end end obj1 = ClassA.new obj2 = ClassA.new obj1.instance_eval do CONST = "Guten tag" def hi0 puts "#{CONST} I am B" end def hi1 puts "Good bye #{self.class.name}" end end obj1.hi0 # Guten tag Ich bin B obj2.hi0 # Hello I am A obj1.hi1 # Good bye A obj2.hi1 # Error On 2017/12/29 23:44, Akret Node wrote: > 野口です。 > > ぼくもこの話は気になるので教えてほしいです。 > クラス変数も同様にレキシカルに決定されると理解しています。 > > なので、hi1にある@@valはトップレベル(Object?)から探そうとして失敗し、 > 一方でhi3はClassAにある@@valを見つけることができますのでHelloを出力します。 > > 同じ理屈でいくともとの質問にあるhi1とhi2はどちらも失敗すると思います。 > > class ClassA > @@val="Hello" > > def self.hi3 > p @@val > end > end > > class << ClassA > def hi1 > p @@val > end > end > > ClassA.instance_eval do > def hi2 > p @@val > end > end > > 2017年12月29日 18:48 MASAKI Yuhsuke : >> 内海さん、ありがとうございます。 >> >> 「あれ、でもinstance_evalでクラス変数にはアクセスできたよね…?」 >> と思ってやってみたところ、できませんでした。 >> なるほど… >> >> となると、「instance_eval内でクラスの情報にアクセスしたい」場合の、 >> どうするのが良いでしょうか。 >> アクセサかな? >> >> >> You wrote: >>> 内海@ベルギーです >>> >>> instance_evalはその名前のとおり、インスタンスを evaluate >>> しているのだと考えています。 >>> >>> なのでクラス定数を見たければ >>> >>> p self.class::CONST >>> >>> とすれば見ることができます。 >>> >>> 定数だけでなくクラス・メソッドになりそうに見えるコード >>> >>> def self.hi3 >>> p self.class::CONST >>> end >>> >>> も、instance_eval内ではインスタンスメソッドになりますね。 >>> 一見わかりにくく思えますが、考えればロジカルだと思います。 >>> >>> >>> On 2017/12/29 1:51, Yukihiro Matsumoto wrote: >>>> まつもと ゆきひろです >>>> >>>> 定数の参照はレキシカルに決定されますので、instance_evalなど >>>> では変化しません。 >>>> >>>> >>>> In message "Re: [ruby-list:50630] instance_evalで定数が見えない" >>>> on Fri, 29 Dec 2017 03:24:26 +0900, MASAKI Haruka writes: >>>>> >>>>> 正木です。 >>>>> >>>>> Ruby 2.2のときにも言及したのですが、2.5でも変わっていないので再度お聞かせ下さい。 >>>>> インスタンスの特異クラス内では見えるクラスの定数が、instance_evalでは見えません。 >>>>> >>>>> これは然るべき挙動なのでしょうか。 >>>>> >>>>> *** >>>>> コード: >>>>> >>>>> class ClassA >>>>> CONST="Hello" >>>>> end >>>>> >>>>> obj = ClassA.new >>>>> >>>>> class <>>>> def hi1 >>>>> p CONST >>>>> end >>>>> end >>>>> >>>>> obj.instance_eval do >>>>> def hi2 >>>>> p CONST >>>>> end >>>>> end >>>>> >>>>> >>>>> 結果: >>>>> >>>>> "Hello" >>>>> Traceback (most resent call last): >>>>> 1: fron instance_eval_test.rb:20:in `
' >>>>> instance_eval_test.rb:15:in `hi2': uninitialized constant CONST (NameError) >>>>> *** >>>> >>>