[#17615] substitution at when-clause — Takaaki Tateishi <ttate@...>

立石です.

47 messages 2002/07/01
[#17619] Re: substitution at when-clause — matz@... (Yukihiro Matsumoto) 2002/07/01

まつもと ゆきひろです

[#17621] Re: substitution at when-clause — Takaaki Tateishi <ttate@...> 2002/07/02

At Tue, 2 Jul 2002 02:54:01 +0900,

[#17622] Re: substitution at when-clause — matz@... (Yukihiro Matsumoto) 2002/07/02

まつもと ゆきひろです

[#17624] Re: substitution at when-clause — Takaaki Tateishi <ttate@...> 2002/07/02

At Tue, 2 Jul 2002 13:30:17 +0900,

[#17627] Re: substitution at when-clause — matz@... (Yukihiro Matsumoto) 2002/07/02

まつもと ゆきひろです

[#17630] Re: substitution at when-clause — Takaaki Tateishi <ttate@...> 2002/07/02

立石です.

[#17631] Re: substitution at when-clause — matz@... (Yukihiro Matsumoto) 2002/07/02

まつもと ゆきひろです

[#17635] Re: substitution at when-clause — Takaaki Tateishi <ttate@...> 2002/07/03

立石です.

[#17639] Re: substitution at when-clause — matz@... (Yukihiro Matsumoto) 2002/07/03

まつもと ゆきひろです

[#17644] Re: substitution at when-clause — keiju@... (石塚圭樹) 2002/07/03

けいじゅ@日本ラショナルソフトウェアです.

[#17645] Re: substitution at when-clause — matz@... (Yukihiro Matsumoto) 2002/07/03

まつもと ゆきひろです

[#17647] Re: substitution at when-clause — keiju@... (石塚圭樹) 2002/07/03

けいじゅ@日本ラショナルソフトウェアです.

[#17649] Re: substitution at when-clause — Takaaki Tateishi <ttate@...> 2002/07/03

At Wed, 3 Jul 2002 17:48:58 +0900,

[#17651] Re: substitution at when-clause — keiju@... (石塚圭樹) 2002/07/03

けいじゅ@日本ラショナルソフトウェアです.

[#17730] Re: self in block — masaki <GEC01122@...>

16 messages 2002/07/20

[#17764] Re: self in block — masaki <GEC01122@...>

31 messages 2002/07/22
[#17765] Re: self in block — matz@... (Yukihiro Matsumoto) 2002/07/23

まつもと ゆきひろです

[#17768] Re: self in block — Tanaka Akira <akr@...17n.org> 2002/07/23

In article <1027383423.558649.31176.nullmailer@picachu.netlab.jp>,

[#17769] Re: self in block — matz@... (Yukihiro Matsumoto) 2002/07/23

まつもと ゆきひろです

[#17770] Re: self in block — Tanaka Akira <akr@...17n.org> 2002/07/23

In article <1027404202.545188.1283.nullmailer@picachu.netlab.jp>,

[#17771] Re: self in block — matz@... (Yukihiro Matsumoto) 2002/07/23

まつもと ゆきひろです

[#17772] Re: self in block — Tanaka Akira <akr@...17n.org> 2002/07/23

In article <1027406979.880878.1358.nullmailer@picachu.netlab.jp>,

[#17832] Re: [ruby-cvs] ruby: * random.c: replace with Mersenne Twister RNG. — nobu.nakada@...

なかだです。

17 messages 2002/07/26
[#17835] Re: [ruby-cvs] ruby: * random.c: replace with Mersenne Twister RNG. — matz@... (Yukihiro Matsumoto) 2002/07/26

まつもと ゆきひろです

[#17837] Re: [ruby-cvs] ruby: * random.c: replace with Mersenne Twister RNG. — nobu.nakada@... 2002/07/26

なかだです。

[#17842] Re: [ruby-cvs] ruby: * random.c: replace with Mersenne Twister RNG. — matz@... (Yukihiro Matsumoto) 2002/07/26

まつもと ゆきひろです

[#17886] line number(Re: Re: [ruby-cvs] ruby: * random.c: replace with Mersenne Twister RNG.) — nobu.nakada@... 2002/08/02

なかだです。

[#17893] Re: line number(Re: Re: [ruby-cvs] ruby: * random.c: replace with Mersenne Twister RNG.) — matz@... (Yukihiro Matsumoto) 2002/08/03

まつもと ゆきひろです

[#17897] Re: line number(Re: Re: [ruby-cvs] ruby: * random.c: replace with Mersenne Twister RNG.) — nobu.nakada@... 2002/08/03

なかだです。

[#17973] Re: line number(Re: Re: [ruby-cvs] ruby: * random.c: replace with Mersenne Twister RNG.) — nobu.nakada@... 2002/08/11

なかだです。

[ruby-dev:17727] Re: self in block

From: Minero Aoki <aamine@...>
Date: 2002-07-20 06:02:10 UTC
List: ruby-dev #17727
あおきです。

  In mail "[ruby-dev:17719] Re: self in block"
    masaki <GEC01122@nifty.ne.jp> wrote:

> 正木です。

> > すみません、「self が不定」という点がさっぱりわかりません。self

> initialize の code を書いている時点では不定と言う意味です。勿論呼ばれた
> 時点での context で self は決まります。
> Sequence の設計を色々試していた時の test 結果が、殆んど main だったので、
> つい筆がすべりました。無視してください。 
> 私は従来の block との併用を考えているので、上で言っているのは、どういう
> context で使われるかが前もって分からない特殊な case での話です。

この点は了解です。


以下、引用が前後します。

> > それと「ブロック」はイテレータは含むんですか? 含むとしたら
> > めちゃくちゃ嫌です。ブロックを定義する側からまったく情報を

> イテレータに対しては今まで通りの仕様を使えば良いのでは?

> イテレータに対して新しい仕様を使う必要は殆んどないだろうと思っています。

うーん、では逆に、なぜ self を変える必要があるんでしょうか?つ
まり、なぜ新予約語の追加でもなく、メソッドの追加でもなく、self 
のすりかえなのか、という点を問題にしたいです。正木さんの提示さ
れた例だけではそこのところを突破するだけの決め手に欠けるように
思います。

そしてなぜ self の変更がいやなのかというと、オブジェクトのカプ
セル化原則に違反するからです。self がそのオブジェクトになると
いうことは、インスタンス変数を参照でき private メソッドを呼び
出せるということです。たとえば次のように。

  class C
    def initialize
      @secret = 'ひみつのデータ'
    end

    def once
      yield
    end
  end

  C.new.once {<dummy>
      p @secret     # 参照できてしまう!
  }

イテレータを定義しただけでカプセル化が崩れてしまうのではオブジェ
クト指向プログラム言語である意味が半分以上なくなってしまいます。

Ruby にはそれを崩す例外的手段として instance_eval があるわけで
すが、それはあくまで例外的に、非常時の手段として使うべきもので
あって、平常の手段を達成する一部に使うべきものではありません。
ましてや言語自体に構文的に支援を加えるなどということはもっての
ほかです。ですから以前 instance_eval に引数を渡せる提案のとき
も反対しました。あれは便利になってはいけないものだからです。

繰り返しますが、任意のオブジェクトを self にできる、というのは
「オブジェクト指向言語として」よくないのです。ですから、そうい
う機能を標準構文として持とうというなら、単に互換性をなくさなけ
ればいいという程度の問題ではなくて、オブジェクト指向に代わるパ
ラダイムを提示しなければ十分ではありません。ただしそれは Ruby 
とは呼べないでしょう。

逆に言うと、self をすりかえるのではなくて新しい予約語を追加する
(ブロックを呼び出したオブジェクトを得られるようにする) のならば、
まだわかるのです。その場合なら少なくともオブジェクトの外からの
アクセスになりますから。

それで、その「ブロックを呼び出したオブジェクト」を caller と
呼んだらいいのではないかなあ、self よりはちょっと適切な語じゃないか、
と言ったわけです。caller は当然ながら call + er で call する人
(オブジェクト) のことです。


> object.method(){<x,...> ...}
> 
> で呼ばれる method の定義
>   def method(...)
>     ...
>   end
> のなかでは self はこの method を呼んだ object を指すわけですから
> block 内の self が別の物を指す方が不自然な気がします。

「それは自然だ」という言葉は「それは不自然だ」と言うのとまった
く同じく根拠薄弱です。なぜ不自然なのか教えていただかないと納得
できません。

ぼくは「ブロックの self をすりかえてしまうのはオブジェクト指向
の原則に反する」という根拠を示したので、それを覆すだけの「根拠」
を示していただきたいです。


> ここの所は全く理解できません。
> できれば caller について分かりやすく説明していただけると助かります。

正木さんが欲しいのは「ブロックを呼びだしたオブジェクト」ですよ
ね?「それを self と呼びたい」のが主眼でなくて。ですから、
「call した奴」で caller ではどうか、と言いました。そんなわけ
で以下この機能を仮に caller と呼んでおきます。

それで、いま想定しているのは不定のオブジェクトからブロックが呼
ばれる場合なんですよね。つまりブロックを作ったところからはあず
かり知らぬオブジェクトが caller であるということです。このとき
論点は三つあると思います。

1. そういう状況がどれだけ一般的か

  ブロックを使う頻度によりますが、そんなに多くないような気がする、
  というのが個人的な感想です。特にこの場合ブロックを非イテレータ
  として使い、かつ不定オブジェクトに呼ばれるという二重の制限が
  かかっているので、相当する状況はかなり少ないのではないかと思い
  ます。さらにその中で、caller を使う必要がある場合というのはもっと
  少ないと思います。

2. 他の手段ではどうしてもだめなのか

  たとえばなぜ明示的に引数としてわたすのではだめなんでしょうか?

  グローバル変数はよくない、ローカル変数を使おう、ってのはソフト
  ウェア工学 40 年の歴史の結論 (のひとつ) でした。それはなんでかと
  いうと、使う情報が限定されるからですよね。無駄な情報にはできる
  だけアクセスできないほうが「よい」プログラムと言えます。わざわざ
  情報を増やすからには相当強固な理由がなくてはだめでしょう。
  (たとえば歴代の重要言語が採用して生き残ってきた、など)
  「なんとなく便利そう」では不十分です。

  これが前回書いた「リンクを持つなら○○……」という話です。

3. 邪魔になる場合があるか

  たとえ特殊条件でのみ役立つ機能だろうとも、他の状況でまったく
  邪魔にならないのであれば検討する価値があると思います。ではこの
  場合はどうでしょうか。例としてイテレータについて考えてみます。

    class C
      def iter
	yield
      end
    end

    c = C.new
    c.iter {<dummy>
	p caller   # #<C:0x08b....>   # cと同じ
    }

  この場合 caller は c なので意味ないですね。だいたいイテレータ
  ブロックではイテレータを呼ぶオブジェクトが近くにあるので、
  確かに邪魔にはならないかわりに意味もなさそうです。


1. 2. 3. を総合してみると、

  1. そもそも役に立つ状況があんまりなさそう。
  2. 他の方法で現実的に代替可能。
     しかも caller は無駄に情報を増やし情報隠蔽の大原則に反する。
  3. 一般的な状況においても邪魔にはならないが存在する価値もない。

だから、ないほうがよい。というのがぼくの意見です。


> 参考のためにお聞きしますが、青木さんが現在の block の仕様に不満があると
> したら、それは何ですか?

わりと満足してます。ローカル変数と同名のブロックローカル変数を
宣言したときに警告してくれれば文句ないですね。メソッドの中では
名前空間が完全にフラットな (ネストしない) のが好きです。スレッ
ドとか *_eval のからみがあるのでブロックローカル変数自体はない
と困ると思いますけど、ローカル変数と同じ名前を使える必要性は感
じません。名前空間を分離したかったらメソッド分けろで十分です。
長すぎる手続きは write only code の予兆とも言いますし、メソッ
ドを長くするのを支援する機能はいりません。


> 従来通りの使い方をしている分には何の影響も無いわけで、青木さんが何故
> そんなに反対するのか不可解です。

もう書く必要もないと思いますが、self をすりかえることに対しては、
オブジェクト指向の原則に反するから反対しています。それに、正木
さんが本当に求めてるのは self のすりかえではないとも思います。

caller(仮名) もいりません。self すりかえブロックほどではありま
せんが、積極的に、欲しくないです。その理由は、無駄な情報へのア
クセスを許しちゃいかんという大原則に反するからです。少なくとも
構文で支援するようなもんじゃないです。

ブロック変数のスコープの話にはそれほどは反対しません。どうでも
いいなあ、くらいです。前述のようにいまの仕様でそれなりに満足
してますし、こっちのほうは self や caller と違って言語の根幹に
関わるような話ではないので「使わなければよい」で済みますから。

本物の関数が欲しい、という点にはわりと賛成です。あったら
あったで使いでがありそうですね。
-------------------------------------------------------------------
青木峰郎

In This Thread

Prev Next