前田さん、首藤です。

Ruby と直接関係ある話題ではなくて恐縮です。
以下、断りがない限り Java の話だったりします。

インスタンスの identity について。

> > immutable で、かつ、個々のインスタンスに identity がない (*) 類のクラス
> > (例: String, Number のサブクラス, Boolean, Character)

> > (*) 他にうまい言葉が思いつかないのですが…
> >     Object#hashCode() は、デフォルトの実装だと
> >     インスタンスが違えば極力違う値が得られるようになってます。
> >     それに対して、これら identity がないクラスのインスタンスでは、
> >     hashCode() の値は、文字列 (String)、整数値 (Integer) といった値から
> >     決められてしまいます。インスタンスごとの identity がないんです。

> ==による比較でもStringインスタンスの同一性のチェックが出来ますし、
> 同じ内容のStringリテラルは同一のオブジェクトになることが言語仕様
> にあったような気がするので、hashCode()がoverrideされていることだ
> けを持ってStringインスタンスにidentityがないと言うのは言いすぎの
> ような気がします。

「(あらゆる JVM で) String インスタンスには identity がない」
と言ってしまうと嘘だと思いますが、
「String インスタンスには identity がない、という JVM 実装は『あり』」
だと考えてます。『あり』というのは、JVM 仕様に沿っている、ということです。

  String str1 = "abc";
  String str2 = "ab";
  String str3 = "c";

という状況で、たいていの JVM では
「str1 == (str2 + str3)」は false になりますが、
これが必ず true になる、つまり String インスタンスには identity がない
という JVM 実装もありだと思います。

…なんて話をする前に identity の有無とは何かをきっちり定義しろ、
と言われそうな。考えを整理しないといけません。
identity なし ←→ (同値→同一) ?


> 同じ内容のStringリテラルは同一のオブジェクトになることが言語仕様
> にあったような気がするので、

はい。
(ただ…String インスタンスに identity があることの証左として
 前田さんがこれを挙げた理由を理解できてないです。)
JVM 仕様の 2.3 Literals にこうあります。

  String literals and, more generally, strings that are the values of
  constant expressions are "interned" so as to share unique instances,
  using the method String.intern.

  String リテラルと、値が定数式である string は
  String.intern メソッドでintern されて、
  (値が同じなら) 同一のインスタンスを共有する。


> > もし仮に、ローカル実行と同じセマンティクスで分散実行できる
> > Ruby 処理系を作ろう、という場合は、極力コピーはせずに遠隔参照で扱う一方、
> > 一部のクラスのインスタンス (immutable かつ identity なし) については
> > ネットワーク経由でインスタンスをコピーするか…
>
> Rubyだと、
> 1.instance_eval { @foo = 1 }
> というのがあるので、実はFixnumやnilも完全にimmutableとは言えない
> のですよね。ううむ。

大雑把に言ってしまうと、そういった dynamic な機能が、
将来、処理系の性能向上を図る際に障害になってくると思います。
もっとも、Ruby は、きもちよく楽しく、が第一(?)なので、
そちらをこそ貫いてほしいと思ってます。

あと、特異メソッドについても、分散オブジェクトシステムを作る際には
何か考えないといけないかも。


SHUDO Kazuyuki/首藤一幸   私をたばねないで あらせいとうの花のように
  shudoh / muraoka.info.waseda.ac.jp