ごとけんです

# dev に持って来ました。引用の順序も変えてます。

In message "[ruby-list:18872] Re: constant?"
    on 99/11/24, Yukihiro Matsumoto <matz / netlab.co.jp> writes:

>ある種の「定数」は書き換えを禁止できた方が嬉しい場合があるの
>は当然理解しているのですが、それをプログラミング言語全体の設
>計の中でどう位置付け、どう説明して、どう実装するのが望ましい
>かというのがまだ私の中でクリアになっていません。

ぼくもあまり深く考えていなかったので改めて考察してみたところ、
どうやら定数は安全性を提供するが汚染モデルとは異なる機能を提
供するモノのようです。

まず、定数の効用のうち重要なモノ2つを挙げます。

  (i) typoによるバグを減らす手助け(シンボルよりやや安心)
 (ii) 機能の変更を強制的に一部禁止出来る(うっかり代入抑止)

(i)はたとえばハッシュのキーのように打ち間違いに気づきにくい
場合を想定しています。いっぽう、現在も :: で参照した定数への
代入は出来ないですが、色々な方法で名前空間に入って変更できる
ので特に(ii)に対しては無力です。

さて、再代入できない定数というのはインタプリタがある種の安全
性を保証してくれる名前のことではないでしょうか。この安全性を
上の(i),(ii)に対応させてみます。

  (1) 名前なのでその有効性はインタプリタが検査する
  (2) その名前空間が存在する限り値の一意性が保証される

(1)に対して適切な名前の有効範囲の広さは現状と同じ定数相当で
しょう。ローカル変数やグローバル定数の有効範囲は(i)には不似
合いと思います。問題は(2)にあって、現状では、定数の保護とし
て提供されているのが一切の定数代入を禁止する $SAFE = 4 だけ
だということです。このレベルではユーザが定数を作れないため特
に上記(2)の意図での利用は極めて制限されたものでしかないです。

言い換えれば、いまのRubyにある「オブジェクトの汚染」に基づく
保安性と、名前を保護することによって得られる安全性は異なる要
求を満たすモノだということです。汚染モデルは実行時の安全に対
する保安基準であるのに対し、名前保護はプログラミング支援機構
の一つであってプログラマに対して制限を与えます。思うに両者を
全順序なセキュリティレベルで扱うのには無理があるのかも知れま
せん。

>|>  * 再ロードの問題はどうするの?

>たとえば、ブラウザを含む開発環境のようなものをRubyで開発しよ
>うと思えば、そのような機能が必要になりません? 事実、
>mod_rubyやRuby/JEDのようなシチュエーションでは時々欲しくなります。

なるほどです。

>代入禁止を解除してから再ロードというのは「代入禁止」の挙動が
>未定義なのでだめかどうか判断できません。

仕様を疑似Rubyで書いてみます。再代入を禁止/可能にするメソッ
ドを仮に fixed_attr/unfixed_attr とします。大文字で始まるそ
れぞれの名前 Sym に関連して3つの真偽値を格納する構造体 
K[:Sym] があり、K[:Sym] の各メンバの意味は:

# K[:Sym].used : Symは代入されたことがある
# K[:Sym].open : Symは代入可能
# K[:Sym].tobe : 次の代入の後でのSymの代入可能性

fixed_attr/unfixed_attr および代入操作はそれぞれ:

  def fixed_attr(sym)
    if K[sym].used # fixed_attr の宣言的利用のため
      K[sym].open = K[sym].tobe = false
    else
      K[sym].tobe = false
    end
  end

  def unfixed_attr(sym)
    K[sym].open = K[sym].tobe = true
  end

  def 代入操作
    raise SecurityError unless K[sym].open
    実際の代入
    K[sym].used = true
    K[sym].open = K[sym].tobe
  end

各 K[sym] の初期値や、unfixed_attr の利用可能性はセキュリティ
レベルや共有変数化の行方などと関連させて適宜決める、てな感じ。
前述のように、セキュリティレベルに関する議論も必要かも知れま
せん。

-- gotoken