Forum: Ruby-dev Re: class local instance variable

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
Park Ji-In (Guest)
on 2007-02-16 18:32
(Received via mailing list)
こんばんは。朴 芝印 と申します。

初めてなのでどうかよろしくお願いします。

次のようなcodeを実行してみました。
すると、

mithrandir@losrorien ~/ruby/ruby-svn/trunk $ cat test2.rb
class Merong
  def m
    @__y__ = "Yes!"
  end
end

m = Merong.new
m.m
m.instance_eval { @__x__ = "Yes!" }
puts m.instance_variables.inspect

mithrandir@losrorien ~/ruby/ruby-svn/trunk $ ./miniruby test2.rb
[:@__x__/#<Class:#<Merong:0xb7ed95c4>>, :@__y__/Merong]


こうなりました。

何かinstance_evalの中ではちょっとivar2が違うような気がしますがあれが間違ったとすれば、@__x__/Merong
となるように直したらSingletonも元のコードで動くと思います。
かんちがいだったらすみません。

日本語が下手です、すみません。大目にみてください
Yukihiro M. (Guest)
on 2007-02-17 19:34
(Received via mailing list)
$B$^$D$b$H(B $B$f$-$R$m$G$9(B

In message "Re: [ruby-dev:30362] Re: class local instance variable"
    on Sat, 17 Feb 2007 01:31:28 +0900, "Park Ji-In" 
<removed_email_address@domain.invalid>
writes:

|mithrandir@losrorien ~/ruby/ruby-svn/trunk $ cat test2.rb
|class Merong
|  def m
|    @__y__ = "Yes!"
|  end
|end
|
|m = Merong.new
|m.m
|m.instance_eval { @__x__ = "Yes!" }
|puts m.instance_variables.inspect
|
|mithrandir@losrorien ~/ruby/ruby-svn/trunk $ ./miniruby test2.rb
|[:@__x__/#<Class:#<Merong:0xb7ed95c4>>, :@__y__/Merong]
|
|$B$3$&$J$j$^$7$?!#(B

instance_eval$B$G$O%/%i%9%m!<%+%k$NBP>]$H$J$k%/%i%9$O!"$=$N%*(B
$B%V%8%'%/%H$NFC0[%/%i%9$G$9!#$G$9$+$i!"(BMerong$B%/%i%9$N%/%i%9%m!<(B
$B%+%kJQ?t$O%"%/%;%9$G$-$^$;$s!#(B

$B$G$b!"$3$3$G$O(BMerong$B%/%i%9$N%m!<%+%k%$%s%9%?%s%9JQ?t$K%"%/%;(B
$B%9$G$-$k$H$$$&$N$,0lHLE*$J4|BT$J$s$G$7$g$&$+!#%/%i%9JQ?t$N$H(B
$B$-$K$b$$$m$$$m9M$($^$7$?(B[1]$B$,!"F1$8$h$&$J$3$H$r%/%i%9%m!<%+(B
$B%kJQ?t$KBP$7$F$b9T$&$Y$-$J$s$G$7$g$&$+!#(B

[1] http://www.rubyist.net/~matz/20070104.html#p03
Makoto Inada (Guest)
on 2007-02-18 05:23
(Received via mailing list)
稲田です。

> 
でも、ここではMerongクラスのローカルインスタンス変数にアクセスできるというのが一般的な期待なんでしょうか。

私はそう期待します。プログラムを書いていて instance_eval
を使うときは大抵、既に存在するオブジェクトを直接操作/参照するつもりで書いているので、

1. 
特異クラスの存在を(たとえ知っていても)意識していない、
2. 
そのオブジェクトのインスタンス変数にはすべてアクセスできると思ってしまう、

というふうに考えています。この文脈から見れば、(暗黙で作られた)特異クラスがあるためにオブジェクトの元クラスのローカルインスタンス変数にアクセスできないというのは、唐突な感じがします。
instance_eval 
でなくてオブジェクトに特異メソッドを追加する場合でも、同じように感じます。

これが、明示的にサブクラスを作っていれば、「オブジェクトにはスーパークラスで定義されたアンタッチャブルな部分がある」で簡単に納得できるんですが。
Yukihiro M. (Guest)
on 2007-02-22 03:13
(Received via mailing list)
$B$^$D$b$H(B $B$f$-$R$m$G$9(B

$B$A$g$C$H9M$($?$s$G$9$,!"$^$@G<F@$G$-$k7kO@$,=P$F$$$^$;$s!#(B

In message "Re: [ruby-dev:30382] Re: class local instance variable"
    on Sun, 18 Feb 2007 12:23:18 +0900, "Makoto Inada"
<removed_email_address@domain.invalid> writes:

|> 
$B$G$b!"$3$3$G$O(BMerong$B%/%i%9$N%m!<%+%k%$%s%9%?%s%9JQ?t$K%"%/%;%9$G$-$k$H$$$&$N$,0lHLE*$J4|BT$J$s$G$7$g$&$+!#(B
|
|$B;d$O$=$&4|BT$7$^$9!#%W%m%0%i%`$r=q$$$F$$$F(B instance_eval
|$B$r;H$&$H$-$OBgDq!"4{$KB8:_$9$k%*%V%8%'%/%H$rD>@\A`:n(B/$B;2>H$9$k$D$b$j$G=q$$$F$$$k$N$G!"(B
|
|1. $BFC0[%/%i%9$NB8:_$r!J$?$H$(CN$C$F$$$F$b!K0U<1$7$F$$$J$$!"(B
|2. $B$=$N%*%V%8%'%/%H$N%$%s%9%?%s%9JQ?t$K$O$9$Y$F%"%/%;%9$G$-$k$H;W$C$F$7$^$&!"(B
|
|$B$H$$$&$U$&$K9M$($F$$$^$9!#(B

$B$^$:!"(B1$B$K$D$$$F$G$9$,!"(Binstance_eval$B$G$N%?!<%2%C%H$H$J$k%/%i(B
$B%9$,FC0[%/%i%9$G$J$$$H$^$:$$6ILL$O3N$+$K$"$j$^$9!#$?$H$($P(B
instance_eval$B$NCf$G%a%=%C%IDj5A$r9T$C$?>l9g!"$d$O$j!"$=$N%*(B
$B%V%8%'%/%H$N%/%i%9$K%a%=%C%I$,Dj5A$5$l$k$N$G$O$J$/!"$=$N%*%V(B
$B%8%'%/%H$KFC0[%a%=%C%I$,Dj5A$5$l$k$Y$-$G$7$g$&!#(B

$B$G!"%/%i%9%m!<%+%k%$%s%9%?%s%9JQ?t$NBP>]$,$I$&$"$k$Y$-$+$H$$(B
$B$&$N$O!"8=;~E@$G$O;d$K$O$h$/$o$+$j$^$;$s!#(B

$B$H$$$&$N$b!"0pED$5$s$N4|BT$NA0Ds$H$J$k!V$=$N%*%V%8%'%/%H$N%$(B
$B%s%9%?%s%9JQ?t$K$O$9$Y$F%"%/%;%9$G$-$k!W$H$$$&2>Dj$O!"$=$l$=(B
$B$N$b$N$,%"%/%;%9$G$-$kHO0O$r8BDj$9$k(B($B$N$G!"L>>N=EJ#$,$"$C$F(B
$B$bLdBj$K$J$i$J$$(B)$B%/%i%9%m!<%+%k%$%s%9%?%s%9JQ?t$NB8:_$HL7=b(B
$B$9$k$+$i$G$9!#$=$l$>$l$N%a%=%C%I$O$=$N=jB0$9$k%/%i%9$H$$$&$b(B
$B$N$,B8:_$7$F$$$F!"$=$l$r%/%i%9%m!<%+%k%$%s%9%?%s%9JQ?t$N=jB0(B
$B@h$H$7$FLdBj$J$$$N$G$9$,!"(Binstance_eval$B$G$N%/%i%9%m!<%+%kJQ(B
$B?t$N=jB0@h$r!"$=$N%*%V%8%'%/%H$NFC0[%/%i%9$K$9$k$N$+!"$=$N%*(B
$B%V%8%'%/%H$N%/%i%9$K$9$k$N$+$OG:$^$7$$$H$3$m$G$9!#(B

instance_eval$B$N(B($B%/%i%9%m!<%+%k%$%s%9%?%s%9JQ?t$N(B)$B%?!<%2%C%H(B
$B$r!"$=$N%*%V%8%'%/%H$N%/%i%9$K$9$k$N$O(B($B$d$d<BAu$,LLE]$J$b$N(B
$B$N(B)$BIT2DG=$G$O$J$$$N$G$9$,!"$=$l$K$I$l$@$10UL#$,$"$k$N$+$h$/(B
$B$o$+$i$J$$$H8@$&$N$,@5D>$J$H$3$m$G$9!#(B

$B0J2<$N3F2U=j$G$N%/%i%9%m!<%+%k%$%s%9%?%s%9JQ?t$O$I$N%/%i%9$K(B
$B=jB0$9$Y$-$@$H;W$$$^$9$+!)(B

class Foo
  def foo
    @_foo  # (1)
  end
  def self.foo_c1
    @_foo  # (2)
  end
end

class <<Foo
  def foo_c2
    @_foo  # (3)
  end
end

def Foo.foo_c3
  @_foo    # (4)
end

foo = Foo.new

def foo.foo_i1
  @_foo    # (5)
end

class <<foo
  def.foo_i2
    @_foo  # (6)
  end
end

foo.instance_eval {
  def foo_i3
    @_foo  # (7)
  end
}

                                $B$^$D$b$H(B $B$f$-$R$m(B /:|)
Makoto Inada (Guest)
on 2007-02-22 18:33
(Received via mailing list)
> 
というのも、稲田さんの期待の前提となる「そのオブジェクトのイ
> 
ンスタンス変数にはすべてアクセスできる」という仮定は、それそ
> のものがアクセスできる範囲を限定する(ので、名称重複があって
> も問題にならない)クラスローカルインスタンス変数の存在と矛盾
> するからです。

まさに矛盾なんです。で、私が期待しているのは結局、特異クラスだけは特別扱いをして、自身のクラスローカルインスタンス変数スコープを持たない 
==
常にオブジェクトのクラスのクラスローカルインスタンス変数スコープを使う 
== ようにしてはどうだろう、ということです。
「特異クラス」ということで、特異メソッドと instance_eval
のケースの両方を含んでいますので、まつもとさんの話の前提である、「メソッドの所属するクラスをクラスローカルインスタンス変数の所属先とする」と対立してしまうわけですが。

この案(?) 
によると、変数の所属クラスは下のようになります。
class Foo
def foo
   @_foo  # (1) Foo
end
def self.foo_c1
   @_foo  # (2)  Class
end
end

class <<Foo
def foo_c2
   @_foo  # (3)  Class
end
end

def Foo.foo_c3
@_foo    # (4)   Class
end

foo = Foo.new

def foo.foo_i1
@_foo    # (5)   Foo
end

class <<foo
def.foo_i2
   @_foo  # (6)  Foo
end
end

foo.instance_eval {
def foo_i3
   @_foo  # (7)  Foo
end
}

同じことの繰り返しになりますが、私にとって特異メソッドというのは 
1. 既存のオブジェクトに後からメソッドを付け足せる、2.
クラスで定義されているメソッドと比べて何の制限もない、という点で、とてつもなく便利なわけです。
これが、クラスローカルインスタンス変数の導入と暗黙の(*)
特異クラスのおかげで、2番目のメリットがなくなってしまうのが、惜しい。どうせ内部で暗黙に作られている特異クラスなんだから、クラスローカルインスタンス変数のスコープ決定のときも、なかったことしてしまえ、という発想です。
上の例でいうと、特異メソッド foo_i[123] が Foo#foo 
と同じインスタンス変数 @_foo
にアクセスできるのがうれしいわけです。

(*) 
本当に暗黙なの?暗黙であるべきなの?というのは別に議論されていいと思います。それが 
eigenclass
の意味することなのかもしれませんが。

もう一つ。クラスローカルインスタンス変数があるなら、クラスローカルクラス変数があってもいいような気がします。両方あるならスコーピングのルールも両方で統一されるのが、自然でしょう。
今までは、私の頭がごちゃごちゃになるのでクラス変数の方は考えないようにしてきましたが、クラス変数まで考えると、案外見落としていることがあるかもしれません。今後はこちらも含めて考えてみようかと思っています。

まとまりありませんが、この辺で。

稲田
This topic is locked and can not be replied to.