プロトタイプベース・ ..
357:1
04/02/04 22:43
>>353
スロットっていうと名前で参照できるメンバを動的に追加・削除できるようなイメージがあるけど.
マルチキャストデリゲートは機能の追加・削除が行えるけど名前に関しては静的だよね.
358:1
04/02/04 22:52
class Hoge {
public delegate void PrintDelegate();
public PrintDelegate Print;
}
Hoge hoge = new Hoge();
hoge.Print += new PrintDelegate(_PrintHello);
hoge.Print += new PrintDelegate(_PrintBye);
hoge.Print();
スロットだとこんな感じ?
class Hoge {
}
hoge.PrintHello = _PrintHello;
hoge.PrintBye = _PrintBye;
hoge.PrintHello();
hoge.PrintBye();
359:デフォルトの名無しさん
04/02/05 01:41
ん。
んで slot の場合には、例えば
if a.hasSlot('asText') then
write( a.asText() );
else
write( "unknown object" );
みたいに、「無い」ということも積極的に使うスタイルになります。
DOM の attribute と似てる。
360:デフォルトの名無しさん
04/02/05 13:42
世の中には市場の失敗というのもありうるが、だいたいにおいて市場は良いものの方を選択するから、
結局のところ現状のプロトタイプベースより現状のクラスベースのほうが使いやすいのかも。
(一般的なプログラマにとっては)
一部の神にとっては全てを思い通りに動的にできるプロトタイプベースのほうがいいのかもしれんが。
361:デフォルトの名無しさん
04/02/05 14:27
>>340
> 多分このスレに書き込んでいるほとんどの人はプロトタイプベースOOPL
> を使った開発なんてまともにやったことないでしょう.(私も含めて)
プロトタイプベースは言語よりもむしろ環境として生きるものだと思うなあ。
スクリプトもいいけど、やっぱオブジェクトを記述するメディアとしては
テキストというのは不適合っつーかさ。
>>342
Smalltalk系で言えば、PARTSとかVisualSmalltalkとかあったなあ。
これはクラスベースの環境の上にプロトタイプベース環境を構築したものだから、
ハイブリッドだな。
362:デフォルトの名無しさん
04/02/05 14:44
>>360
> 結局のところ現状のプロトタイプベースより現状のクラスベースのほうが使いやすいのかも。
むしろ、現状を肯定する材料を無意識に探している人も多いんじゃないかと思われ。
クラスベースのほうがいいという理由として最適化を出した人がいるけど、
それで何パーセントパフォーマンスが上がるのか。その何パーセントかが
クリティカルになるシステムが一体どれだけあるのか。
クラスで整理したほうがいいと言いながら、
後になってから1つのクラスを2つのサブクラスに分割する時の手間は
「仕方ない」で済ませてしまう。動的型付ならともかく、静的型付で新しい
サブクラスに応じて型体系をきちんと見直して、インターフェイス型の
定義を洗い直して変数やメソッドの型を適切に修正したりするのは結構
無視できない量の作業のはずなのに。
そういったことを「言語のために負っている手間」と認識せずに
「本質的に仕方ないこと」と看倣している限りは、周りが皆動いてからで
ないと動かないんだろうな。
363:デフォルトの名無しさん
04/02/05 15:05
>362
そういったクラスによるデメリットも、プロトタイプベースの動的さ故に生まれるカオスよりは
マシだということなのかもしれない。
普通のプログラマには枠が有ったほうがいいのかも。あまりに動的だと乗りこなせない。
世の中、Smalltalk, C++, Java とクラスベースで来てるから、
単に流れでクラスベースなだけかもしれないけど。
Kay, Stroustrup, Gosling は何故クラスベースを選択したんだろう。好み?
364:デフォルトの名無しさん
04/02/05 15:11
正直、インターフェース型さえしっかり設計されてれば、
動的だろうが静的だろうが、クラスだろうがプロトタイプだろうが関係ないような。
365:デフォルトの名無しさん
04/02/05 15:59
>>363
> Kay, Stroustrup, Gosling は何故クラスベースを選択したんだろう。好み?
他の2人はともかく、Alan KayはSqueakのMorphでインスタンスベース風な
環境に取り組んでいるのですが・・・
366:デフォルトの名無しさん
04/02/05 16:19
>>362
・クラスベースの方が数倍は速い.(実行速度のことね)
・型付けされていればバグが減る.
ちなみに俺はクラスベースの方がいいとは思ってないが,
クラスベース<プロトタイプベースとも思ってない.
367:デフォルトの名無しさん
04/02/05 16:41
>>366
> ・クラスベースの方が数倍は速い.(実行速度のことね)
これは具体的に何と何の比較?SelfとSmalltalkでこの差が出る?
それともSelfとC++?
どっちかっつーと、クラスベース/プロトタイプベースの比較以上に
プリミティブ型や演算子などの扱いとかのほうが
直接パフォーマンスに効いてくるんじゃないかと思うが。
あと、VMかネイティブコンパイラかのほうが大きいかもしれない。
> ・型付けされていればバグが減る.
プロトタイプベースでも静的型付は可能でしょ。
ただ単に、プロトタイプベースの良さを引き出すためには
多くの言語が動的型付を採用しているというだけの話で。
実際、スロットの動的追加はsubtypingとして元の型のままと看倣せるし、
スロットの変更についても、代入と同様の型チェックを実行するだけの話では?
スロットの削除はコピー生成時からあるスロットに対してのみ削除を禁止して、
動的に追加されたスロットは削除してもいいと思うし。
368:367
04/02/05 16:55
つーか、このスレって
(1) 既存のオブジェクト指向プログラミング言語/環境の比較として、
クラスベースとプロトタイプベースのものに分けて比較する。
(2) オブジェクト指向プログラミング言語/環境を設計するための
技術要素としてのクラスベース/プロトタイプベースの利点/欠点を
比較する。
のうち、どっちなんだろ。
最初のころは「プロトタイプベース・スクリプト言語へのクラス導入ハンターイ」
という意見があったんで(2)もアリだと思っていたのだが、
もし(1)のみが焦点ならば、>>367はとんでもなく的外れになるわけだが。
369:デフォルトの名無しさん
04/02/05 17:20
つか
>実際、スロットの動的追加はsubtypingとして元の型のままと看倣せるし、
動的に追加したら、結局、動的に束縛しなきゃならないわけで、
静的型チェックによる速度向上なんか望めないような。。。
370:デフォルトの名無しさん
04/02/05 17:22
んー漏れは >>1 にあるように;
>オブジェクトを複製または継承によって生成を行う言語,
>プロトタイプベース・オブジェクト指向言語について語りましょうよ.
という趣旨で参加してますた。
だからクラス付き言語との比較の話は「スレ違いだけど、まぁ仕方ないか」って感じで。
371:デフォルトの名無しさん
04/02/05 17:29
漏れはクラスベースかプロトタイプベースかは、言語の優劣のような
ものとは無関係だと思うね。
「オブジェクト指向」を純化させると「プロトタイプベース」になる
というのは理解できるけれども、クラスという仕組みはやはり便利だし、
「プロトタイプベース」であることの利点を述べているつもりでも、
実はその言語が「動的変更をどれだけ許すか?」を語っているだけ
じゃないかと思うことが良くある。
そして「動的vs静的」は古来「柔軟性vs効率」の戦いになって不毛。
372:デフォルトの名無しさん
04/02/05 18:02
JavaScript でプロトタイプベースなOOやってみてるウェブサイトってないですか?
URLリンク(member.nifty.ne.jp)
URLリンク(www.tokumaru.org)
以外で。
JavaScriptなのは他にプロトタイプベース言語知らないから。
ドキュメント豊富なのってこいつくらいだよね。SelfだのNewtonScriptだのは全然見かけないし
373:1
04/02/05 19:16
>>368 >>370
スレ違いではないと思うけど,あまりクラスベースと比較ばっかしてても
>>371の言う通りではないかなぁ.
# というか個人的につまらないだけですが…w
374:デフォルトの名無しさん
04/02/05 19:54
>>371
クラスベースでも動的変更は出来るから,
「クラスベース: 静的」「プロトタイプベース: 動的」とは言えない.
プロトタイプベースとクラスベースの本質的違いはそこではない.
375:デフォルトの名無しさん
04/02/05 22:20
本質とか純化とか優れているとかじゃなくて、もちっと具体的にうれしいのか
説明してくれると嬉しいんだが。RAD だのオブジェクトを触って変更できるって
動的言語なら大抵そうじゃない?オブジェクトを触るっていうけど、別にクラスベース
だって動的言語なら大抵オブジェクトを操作できますよね?一オブジェクトだけ
メソッド追加/変更とか。
理論的にシンプル(概念が少ないから)だから…というくらいしかわかんないなぁ。
で、とりあえずやってみりゃ分かるだろと思って Self ってのを試そうと
思ったんだが x86 じゃ動かないみたいだし。結局 2ch で聞いてしまうわけだ…。
376:デフォルトの名無しさん
04/02/05 22:36
動的なクラスベースっていうと・・
Smalltalk以外には何があるの?
377:デフォルトの名無しさん
04/02/05 22:51
そんなのいっぱいあるんじゃねーの?スクリプト系とか。Lisp 系も大抵そうだろう。
違いとかじゃなくてクラスベースだとマズーだけどプロトタイプだとウマーな点を指摘して
やればいいだけんじゃないのかと思われ。
378:デフォルトの名無しさん
04/02/05 23:10
1オブジェクトだけメソッド追加/変更なんて出来るクラスベース言語ってあるのかな。。
クラス自体を新しく作って、オブジェクトのクラスを変更するんならともかく。
漏れ的にはプロトタイプベースの言語でも大抵なんでもできるんじゃないの、って立場なんで、
逆に 375 の人に「なんでクラス付き言語の方がいいの?」ってのを具体的に聞いてみたい。
広く使われていてライブラリが充実しているので Java がいい、とか、実行速度が速くて
ジェネリックスがやりやすいので C++ がいい、とかさ。
379:デフォルトの名無しさん
04/02/05 23:13
もういっちょ。
プロトタイプベース言語はクラスベース言語の何かについての反省から生まれてきたわけではないし、
誰も「喪前らクラスベース言語はマズイですよ」とも言ってないわけだから、
「クラスベースだとマズー」→「プロトタイプベース言語でウマー」ってのが無きゃならない・あるはずだ、
ということはないと思うんだけど。
380:デフォルトの名無しさん
04/02/05 23:25
>>375
> だって動的言語なら大抵オブジェクトを操作できますよね?一オブジェクトだけ
> メソッド追加/変更とか。
クラスベースできるけどその言語本来が狙っているやり方じゃないような。
純粋にクラスベースで1つのオブジェクトだけメソッドやイ変数を追加しようとしたら、
そのために動的にクラスを生成してそのクラスのインスタンスに化けるという操作
が必要になる。
じゃあその動的に生成したクラスの名前はどうするってこととか、どっかシステム中
に元のクラスを参照している部分があったらそこも変更しなきゃいけないのかとか、
結構面倒なことになる。
で、例えばクラス名は適当に番号か何かを付けて自動的に名前を生成しても、
そんな適当な名前がクラスライブラリに混入することはクラスベースで想定していた
「良いプログラミング」とはかけ離れたものになるんじゃないかな?
そういうクラス絡みの「やり難さ」を取り除くには、クラスでの定義とは独立して
メソッドや変数を追加できる機構が必要になると思われ。
俺的には、そういう機構さえあれば、別にクラスが存在していてもいいと思ってる。
381:デフォルトの名無しさん
04/02/05 23:31
あ、そうなのか!どうやら漏れはとんでもない勘違いをしていたようだ…。
てっきり、クラスベースのなにかを反省して出来たのかと思ったけど、
そうじゃないわけね。うーむ、とりあえず試してみたいがなんか x86 で
動くやつのオススメをキボンヌ。
> 1オブジェクトだけメソッド追加/変更なんて出来るクラスベース言語ってあるのかな
例えば CLOS ではできたYO。基本はクラス単位だけどオブジェクト単位でも定義できる。
ついでにメソッドコンビネーションで特定のメソッドの前後に処理を追加するとかもできるのが面白い
と思った。つまり特定のオブジェクトのあるメソッドの前にだけ処理を挿入とかできるウマー。
ウマーな例:
このオブジェクトはユーザーが触ったやつだから消えるときは知らせよう→削除しますた表示をオブジェクトに追加
382:デフォルトの名無しさん
04/02/05 23:37
ま、現実的な市場のニーズはないんだけどな。
漏れのような現場の土方には思考の訓練の道具ってだけだな
383:デフォルトの名無しさん
04/02/05 23:37
>>369
> 動的に追加したら、結局、動的に束縛しなきゃならないわけで、
> 静的型チェックによる速度向上なんか望めないような。。。
いや、他のオブジェクトのメソッドからは、追加したメソッドは叩けないだろ。
静的型チェックしているから。
動的に追加したスロットは、一緒に動的に上書き変更したメソッドの中からしか
叩けないんじゃないかな。
で、それらのスロットを取り除く時には動的チェックするか、あるいは
一緒に動的に追加したスロット群全部をいっぺんに取り除くことにする
って感じでどうよ?
かなり窮屈なプロトタイプベースだが(苦
384:381
04/02/05 23:40
>純粋にクラスベースで1つのオブジェクトだけメソッドやイ変数を追加しようとしたら、
>そのために動的にクラスを生成してそのクラスのインスタンスに化けるという操作
>が必要になる。
そんなことは無かったと思うけど…。
(defmethod hoge ((self クラス名)) ....)
(defmethod hoge ((self (eql オブジェクト))) ...)
こんだけなんで、単にメソッド検索時にオブジェクト>クラスな
優先順位になってただけじゃないかなと思われ。
でもクラスがどうのとかはいいからプロトタイプベースの処理系を
オススメしてくれょぅ。触ってみたいんだよぅ。Self が動かなくて
悔しいんだよぅ。x86 で動かせるやつ。OS は Win か Linux か *BSD くらいで。
385:デフォルトの名無しさん
04/02/05 23:42
JavaScript
386:デフォルトの名無しさん
04/02/05 23:48
>>381
プロトタイプベース言語は、オブジェクト指向言語の一派というよりも、
ミンスキーのフレーム理論の直接の形式化で、
「オブジェクト」ではなく「フレーム」を基本的なデータ構造としています。
URLリンク(www.symlab.sys.i.kyoto-u.ac.jp)
のp38あたりからを参照。
387:デフォルトの名無しさん
04/02/05 23:50
それがオススメですか。んじゃ遊んでみます。
一応年のため聞くけど、処理系は IE とか Mozilla でいいんですよね?
388:デフォルトの名無しさん
04/02/05 23:53
>>384
上の方にリンクが載っているが、Io とか Cecil なら x86 でも動くはず。
Win で Cecil 動かしてる人がいるから参考まで。
URLリンク(www.kmonos.net)
389:デフォルトの名無しさん
04/02/05 23:54
>387ってずいぶん信じやすい香具師なんだな。
390:デフォルトの名無しさん
04/02/05 23:56
ん。すくなくとも Self の論文は Smalltalk を引き合いにクラスベースの不自然さを
淡々と説いているが…? ただ、結果としてはこのスタンスがまずかった。
オブジェクトベース(aka プロトタイプベース)がまるでクラスベースの対局だという
ような考え方を一般に植え付けてしまったから。
プロトタイプベースって言葉が悪いんだよね。おそらくここで意見を交わし合うべきは
オブジェクトベース(あるいはクラスを意識するならインスタンスベース)のオブジェクト vs
クラスベースのオブジェクトなのであろうかと思うのですが、いかがでしょうか?>1さん
つまり、オブジェクトが自由に値スロットやメソッドスロットを追加できるとき、どんな
メリット(やデメリット)があるのかとか、スロットへのアクセスにはどんな方法がベターか
とか、そんな話で盛り上がった方がおもしろいと、まあ、そんなふうに思うわけです。
プロトタイプベースとくくってしまうと、オブジェクトの移譲先としてプロトタイプが良いか、
クラスが良いかという結局、好みの問題に終始してしまうので不毛かなと。
391:1
04/02/05 23:56
>>381
ここにあるSelfのcygwin版,動かないんだよねぇ…
URLリンク(www.gliebe.de)
とりあえず,Cecilなんてどうでしょうか?
URLリンク(www.cs.washington.edu)
Interpreterをダウンロードして展開すればすぐに遊べますよ.
ここでも見ながら→URLリンク(www.kmonos.net)
俺はまだほとんど使ってないけど…コレはかなり楽しそう.
392:1
04/02/06 00:03
>>388 マッタリしてたら被ってしまった.ゴメン.
つかレス速っw
>>390
>プロトタイプベースって言葉が悪いんだよね。おそらくここで意見を交わし合うべきは
>オブジェクトベース(あるいはクラスを意識するならインスタンスベース)のオブジェクト vs
>クラスベースのオブジェクトなのであろうかと思うのですが、いかがでしょうか?>1さん
激しく同意です.
ただ私は無知なのでなかなか積極的に話題振ったりできませんが…
393:デフォルトの名無しさん
04/02/06 00:08
なんというか,クラスベースよりプロトタイプベースの方が純粋にオブジェクト指向
してるとは思えないなぁ.
クラスがない方が自然なの気がするけど,それ以上にプロトタイプのチェインは
不自然な概念だと思う.
394:デフォルトの名無しさん
04/02/06 00:10
開発環境を聞こうと再び 2ch を覗いたら、なんだ、他にもいっぱいあるじゃないか。
>>389 ちょっと前でも JavaScript って話だったじゃないか……正直 age に騙された。
お前らいい香具師らじゃないか。遊んでみるYO!!
で、>>386 のを脳内解釈したところ、
×クラスベースがあってそれをほにゃほにゃしてプロトタイプベースができた
○プロトタイプベースを実現した。で、クラスと比較して〜
という理解でいいのかな。
395:デフォルトの名無しさん
04/02/06 00:16
まず,純粋な(クラスもプロトタイプチェインもない)オブジェクトがあって,
でもそれでは,1つ1つのオブジェクトが同じメソッドをバラバラに持ってるのは
効率が悪いから,プロトタイプやらクラスやらが導入されたんじゃないの?
396:デフォルトの名無しさん
04/02/06 00:21
>>390 と >>392 に同意
やっぱ焦点はオブジェクト単位のスロット管理のpros/consだわな。
つまり>>384さんの流れで言うと、CLOSもインスタンスベースとしての機能「も」
持っているわけで。
397:デフォルトの名無しさん
04/02/06 00:23
>>384
何度か出ているけど、CLOS をクラスベースの引き合いに出すのは混乱するから
やめたほうがよいと思いますよ。CLOS のオブジェクトは、スロットこそクラスベース
のオブジェクトと同様にクラスを鋳型にしていますが、メソッドのほうは総称関数という
まったく別の機構で扱われているわけで、誤解を恐れずいうなら、これは抽象データ型
だとかオブジェクト指向とかいった次元を超越した機構なわけですから。
398:380
04/02/06 00:35
>>384
まぎらわしい書き方してすまんです。>>380での「純粋にクラスベースで」とは、
「クラスが管理しているスロット定義情報のみで」という意味のつもりでした。
ので、>>834で挙げてもらったCLOSでの例は「純粋にクラスベースで」には
含めないつもりでした。
で、>>381に挙げてもらった例には大枠で賛成です。
特に、言語レベルでbeforeやafterが使えるのはイイねえ。
399:380
04/02/06 00:43
>>390
> つまり、オブジェクトが自由に値スロットやメソッドスロットを追加できるとき、どんな
> メリット(やデメリット)があるのかとか、スロットへのアクセスにはどんな方法がベターか
> とか、そんな話で盛り上がった方がおもしろいと、まあ、そんなふうに思うわけです。
もうちょい厳密に言うと、それを言語仕様または処理系レベルでサポートすることの
メリット/デメリットということで、どうでしょうか?
そういうオブジェクトを構築できるかどうかということになると、
クロージャを扱える言語/処理系ならば、そういうクラス/オブジェクトを
ユーザの手で作ることができるわけで、それではむしろデザインパターンと
変わらなくなるような気がするので。
400:380
04/02/06 00:44
>>397
> メソッドのほうは総称関数という
> まったく別の機構で扱われているわけで、誤解を恐れずいうなら、これは抽象データ型
> だとかオブジェクト指向とかいった次元を超越した機構なわけですから。
でもマルチメソッド萌え・・・スレ違いスマソ。
401:デフォルトの名無しさん
04/02/06 01:05
>>399
まあ、それは言わずもがなでしょう。オブジェクト指向におけるオブジェクトの
オールマイティ性(と、同時にそれが苦手とすること)ってのは Smalltalk システムが
早々と明らかにしてしまっていますから、ことさらにここでそれを強調する必要もなかろうかと。
そんなことを言い出したら、Lisp 屋さんが出てきて、そんなのオブジェクトなんか使わんでも
俺たちならもっと巧くやれる!ってなことになりかねない(笑)。
402:デフォルトの名無しさん
04/02/06 01:11
>>399
スレの流れ的には大賛成だが、
>クロージャを扱える言語/処理系ならば、そういうクラス/オブジェクトを
>ユーザの手で作ることができるわけで、
こっちの方が超ステキ!(キラン
403:デフォルトの名無しさん
04/02/06 12:20
>>207
Smalltalkでプロトタイプベースとは、おめでてぇや。
Selfが動くVMイメージ持ってるの?
404:デフォルトの名無しさん
04/02/06 12:36
>>402
禿同
405:デフォルトの名無しさん
04/02/06 14:08
でもクロージャでオブジェクト作るの結構メンドイんだよな.
406:デフォルトの名無しさん
04/02/06 17:00
>403
、ミ川川川彡 ,ィr彡'";;;;;;;;;;;;;;;
ミ 彡 ,.ィi彡',.=从i、;;;;;;;;;;;;
三 ギ そ 三 ,ィ/イ,r'" .i!li,il i、ミ',:;;;;
三. ャ れ 三 ,. -‐==- 、, /!li/'/ l'' l', ',ヾ,ヽ;
三 グ は 三 ,,__-=ニ三三ニヾヽl!/,_ ,_i 、,,.ィ'=-、_ヾヾ
三 で 三,. ‐ニ三=,==‐ ''' `‐゛j,ェツ''''ー=5r‐ォ、, ヽ
三. 言 ひ 三 .,,__/ . ,' ン′  ̄
三 っ ょ 三 / i l,
三. て っ 三 ノ ..::.:... ,_ i ! `´' J
三 る と 三 iェァメ`'7rェ、,ー' i }エ=、
三 の し 三 ノ "'  ̄ ! '';;;;;;;
三 か て 三. iヽ,_ン J l
三 !? 三 !し=、 ヽ i ,.
彡 ミ ! "'' `'′ ヽ、,,__,,..,_ィ,..r,',",
彡川川川ミ. l _, , | ` ー、≡=,ン _,,,
ヽ、 _,,,,,ィニ三"'" ,,.'ヘ rー‐ ''''''"
`, i'''ニ'" ,. -‐'" `/
ヽ ! i´ /
ノレ'ー'! / O
407:デフォルトの名無しさん
04/02/07 00:08
このスレではプロトタイプベースの作り方なんて話も OK なんですか?
辞書でも用意して、名前と値をぽんぽん追加してくだけでいいんかな。
408:1
04/02/07 20:15
>>407
クラスベースでプロトタイプベースを実現する方法ですか?
それともプロトタイプベース言語の実装方法?
どっちにしても興味深いですね.
409:デフォルトの名無しさん
04/02/07 22:05
え、そうかな。基本的にハッシュでも用意して名前に対応する値や関数を
突っ込むだけでしょ?で、オブジェクト複製用のオペレータがあれば
一応プロトタイプベースデキタ!くらいならスクリプト系言語なら簡単に
できません?他にも何かいるのかな?
410:デフォルトの名無しさん
04/02/07 22:16
>>409
委譲機構
411:デフォルトの名無しさん
04/02/07 22:25
委譲するオブジェクトのリストでも持っといて、自分のスロットに
見つからなかったらそっちから順番に検索…とかじゃ駄目っすかね?
412:n
04/02/08 00:08
class Proto
attr_accessor :slot,:proto,:mixin
def initialize; @slot = Hash.new; @proto = nil; @mixin = Array.new; end
def inherit; obj = Proto.new; obj.proto = self; return obj; end
def call(key); if @slot.key?(key) then @slot[key].call else self.proto.call(key) end;end
def set(key,val); @slot[key]=val; end
def get(key)@slot[key]end
end
foo = Proto.new
foo.set "foo",proc{puts"foo"}
foo.set "hello",proc{puts"Hello,Foo!"}
bar = foo.inherit
bar.set "bar",proc{puts"foo"}
bar.call("foo")
bar.call("hello")
hoge = bar.inherit
hoge.set "hello",proc{puts"Hello,Hoge!"}
fuga = hoge.inherit
fuga.call("foo")
fuga.call("hello")
foo.call("hello")
こんな感じですか?
413:デフォルトの名無しさん
04/02/08 00:10
なにが?
414:デフォルトの名無しさん
04/02/08 00:20
>>3-4
聞いたこともない言語ばかりだなぁ
415:デフォルトの名無しさん
04/02/08 03:23
>>411-412
たとえば、call でそのメソッドを起動したとき、レシーバの get "foo" が "foo" なら "yes"、
そうでなければ "no" と答える "is_foo?" というメソッドスロットを foo に追加できますか?
416:デフォルトの名無しさん
04/02/08 03:53
追加される proc の側で追加先のオブジェクトを参照できる必要があるね。
python みたいに proc の引数に明示的に self 相当のものが。
417:デフォルトの名無しさん
04/02/08 06:21
>>405 それは、ひょっとしてギャグで言ってるのか!?
>>406 意味不明過ぎ。
418:デフォルトの名無しさん
04/02/08 06:34
なんかポインター見失っちゃったんだけど、
Squeak上で動くSelfとか、Smalltalk無しで動くSelfとか、
Sunの研究部門が数年前に出してたっけ?もしかして。
419:デフォルトの名無しさん
04/02/08 06:42
あ、Self 4.1〜4.2が1,2年前に出たのか。
10年近く前に探しに行った時は、
・Smalltalk VMが必要なバージョンとか、
・Sparc上で動くバイナリしかなくて、
ダウンロードしても実行に困った覚えがあったっけ。
今はMac上に移植されてるのか。おまぃら、いい時代に生きてますね
URLリンク(research.sun.com)
--------------------------------------------------------------------------------
Self 4.2
Self 4.2 is the most recent public release (June 2003). It features the optimizing compiler on the PowerPC. Jump here to find out more.
--------------------------------------------------------------------------------
Self 4.1
Self 4.1.6 was the most previous public release (September 2002). It runs on the Macintosh as well as on machines from Sun Microsystems, Inc. Jump here to find out more.
--------------------------------------------------------------------------------
Self 4.0
Self 4.0 was a previous public release (July 1995). Jump here to find out more.
420:デフォルトの名無しさん
04/02/08 13:07
Pythonってクラスベースに入るの?
classといってもオブジェクト生成関数みたいなもんだよね?
421:デフォルトの名無しさん
04/02/08 13:15
> Pythonってクラスベースに入るの?
Yes.
> classといってもオブジェクト生成関数みたいなもんだよね?
Yes.
ところでPythonはインスタンス固有のメソッド(Rubyでいう特異メソッド)
を作れるのに、多分誰も利用してませんね・・・。
422:420
04/02/08 13:24
>>421
俺は結構使ってる.だからクラスベースって言われるのに違和感があった.
こういうのもクラスベースに入るんだね.
423:n
04/02/08 14:54
>> 415
class Proto
attr_accessor :slot,:proto
def initialize; @slot = Hash.new; @proto = nil end
def inherit; obj = Proto.new; obj.proto = self; return obj end
def call(key,*arg)
if @slot.key?(key) then
return @slot[key].call(self,*arg)
else
obj = self
while obj = obj.proto; if obj.slot.key?(key) then return obj.slot[key].call(self,*arg) end end
end
end
def set(key,val); @slot[key]=val; end
def get(key)@slot[key]end
end
foo = Proto.new
foo.set "foo","foo"
foo.set "is_foo?",lambda{|this|this.get("foo") == "foo" ? "yes" : "no"}
puts foo.call("is_foo?") #=>"yes"
bar = foo.inherit
bar.set "foo","bar"
puts bar.call("is_foo?") #=>"no"
ちょっと強引ですが、こうすればレシーバのメソッドも呼べます。
424:デフォルトの名無しさん
04/02/08 16:35
>>423
乙。bank_account を組んでみました。
bank_account = Proto.new
bank_account.set "get_balance", proc{|this| this.get "balance"}
bank_account.set "set_balance", proc{|this, x| this.set "balance", x}
bank_account.call "set_balance", 200
bank_account.set "deposit", proc{|this, x| this.call "set_balance", (this.call "get_balance") + x}
bank_account.call "deposit", 50 => 250
bank_account.set "withdraw",
proc{|this, x| this.call "set_balance", [0, (this.call "get_balance") - x].max}
bank_account.call "withdraw", 100 => 150
bank_account.call "withdraw", 200 => 0
my_account = bank_account.inherit
my_account.call "set_balance", 100 => 100
my_account.call "deposit", 50 => 150
my_account.call "withdraw", 100 => 50
425:デフォルトの名無しさん
04/02/08 16:36
>>424
続き、
stock_account = bank_account.inherit
stock_account.set "get_num_shares", proc{|this| this.get "num_shares"}
stock_account.set "set_num_shares", proc{|this, x| this.set "num_shares", x}
stock_account.call "set_num_shares", 10
stock_account.set "get_price_per_share", proc{|this| this.get "price_per_share"}
stock_account.set "set_price_per_share", proc{|this, x| this.set "price_per_share", x}
stock_account.call "set_price_per_share", 30
stock_account.set "get_balance",
proc{|this| (this.call "get_num_shares") * (this.call "get_price_per_share")}
stock_account.call "get_balance" => 300
stock_account.set "set_balance",
proc{|this, x|
this.call "set_num_shares", Float(x) / (this.call "get_price_per_share")
this.call "get_balance"}
stock_account.call "deposit", 60
stock_account.call "get_num_shares" => 12.0
426:デフォルトの名無しさん
04/02/08 21:12
>>421-422
どうやって作るの?データは簡単に作れるけどメソッドの追加ができん……
427:デフォルトの名無しさん
04/02/08 21:14
まったくPythonは素晴らしいね。
Rubyとかいう出来損ないの言語とちがって。
428:デフォルトの名無しさん
04/02/08 21:22
荒れるからやめれ。
429:デフォルトの名無しさん
04/02/08 21:48
ヤバイ。 Ruby ヤバイ。まじでヤバイよ、マジヤバイ。Ruby ヤバイ。
まずオブジェクト指向。もうただのオブジェクト指向なんてもんじゃない。純粋オブジェク指向。
オブジェクト指向といとかっても「基本型は別なんでしょ?」とか、もう、そういうレベルじゃない。
何しろ全部オブジェクト。スゲェ!なんか特別扱いとか無いの。数値も文字列も全部オブジェクト。
<!-- しかも他の言語をリスペクトしてるらしい。ヤバイよ、(パク)リスペクトだよ。
だって普通は他の言語をリスペクトしといて機能取り込んだ後叩くとかしないじゃん。
だってリスペクトしたって事はどっちかっつーと恩があるわけじゃん。
リクペクトしといてあとてやーいやーいザマーみろとか言わないっしょ。だから普通はリスペクト元の言語貶したりしない。話のわかるヤツだ。
けど Ruby はヤバイ。そんなの気にしない。貶しまくり。
他言語から心底ウザがられても「悔しがってる」「負けおしみですか?」とかよくわかんないくらい信者強気。ヤバすぎ。 -->
オブジェクト指向っていったけど、もしかしたらオブジェクト指向が最後のパラダイムかもしんない。でも最後って事にすると
「じゃあ、Ruby 最強?」
って事に<!-- 信者の脳内では-->なるし、それは誰も止められない。ヤバイ。誰にも止められないなんて凄すぎる。
あと超ユーザビリティ高い。end で終るから。shift 押さなくて良いんだって。ヤバイ。凄すぎ。括弧は最悪インデントは基地外。怖い。
それに超拡張モジュール書きやすい。GC のおかげらしい。参照カウントとかすると拡張モジュール内でその辺気にしなきゃいけないじゃん?でも Ruby は平気。C スタックとか平気でスキャンしてくれる。C スタックて。小学生でも直接操作しねぇよ、最近。
でも Ruby は全然平気。 C を C のまま扱ってる。凄い。ヤバイ。
とにかく貴様ら、Ruby のヤバさをもっと知るべきだと思います。
そんなヤバイ Ruby で作られたアプリケーションとか超偉い。もっとがんばれ。超がんばれ。
430:デフォルトの名無しさん
04/02/08 21:58
コピペ厨キターーー微妙に主旨がバラバラな内容なのがヘタレだな
431:デフォルトの名無しさん
04/02/08 22:12
先日Rubyを齧ってみました。
確かにうんこの味がしました。
Rubyはうんこです。
間違いありません。
Rubyなんて大層な名前はやめて、○んこと改名すべきです。
432:デフォルトの名無しさん
04/02/08 22:23
簡単、軽量に実装できるからNewtonみたいなのも採用出来たんでしょうね。
433:デフォルトの名無しさん
04/02/08 22:56
>>426
421-422 じゃないけど、Python 学習をかねて調べてみました。
class Foo:
def f(self): return "I'm of class"
foo = Foo()
foo.f() => "I'm of class"
bar = Foo()
bar.f() => "I'm of class"
def newF(): return "I'm *not" of class"
foo.f = newF
foo.f() => "I'm *not* of class"
bar.f() => "I'm of class"
def anotherF(self): return "I'm *also* of class"
Foo.f = antoherF
foo.f() => "I'm *not* of class"
bar.f() => "I'm *also* of class"
434:426
04/02/08 23:07
>>433
それではただ関数を入れてるだけではないか。
漏れの求めるメソッドは↓で言うところの呼び出し時の冗長な obj を省ける
いわゆるメソッドが追加できるのか調べているのだが…。
class Object:
pass
obj = Object();
def say(self, msg):
print msg
obj.say = say
print obj.say
obj.say(obj, "hello") # obj ウザー
obj.say(obj, "humm") # ウザー
435:デフォルトの名無しさん
04/02/09 13:48
>>426
newモジュールを使うナリよ。
436:デフォルトの名無しさん
04/02/10 21:14
>>435
スマソ低能なのでマニュアル見たんだが良くわらん.サンプルキボンヌ
437:デフォルトの名無しさん
04/02/10 22:43
426がちゃんと読んでないだけかと思われ
438:デフォルトの名無しさん
04/02/11 01:18
>>435
そうなりか! さんくす
Python 学習を兼ねて、調べて書いてみました。
import new
class Obj:
def m(self): print "method of " + self.__class__.__name__
obj1 = Obj()
obj1.m() => 'method of Obj'
obj2 = Obj()
obj2.m() => 'method of Obj'
def m(self): print "method *not* of " + self.__class__.__name__
obj2.m = new.instancemethod(m, obj2, Obj)
obj2.m() => 'method *not* of Obj'
obj1.m() => 'method of Obj'
obj3 = Obj()
obj3.m() => 'method of Obj'
439:デフォルトの名無しさん
04/02/11 15:46
うぉ.格好悪い書き方だなぁ.これってクラスベースだからなのか,
Python固有の問題なのかどっち?
440:デフォルトの名無しさん
04/02/11 16:08
instancemethodが使えるのは後付けだからなぁ・・・。
クラスベースだからでもあり、Pythonだからでもあり。
本格的に使用するもんじゃないと思われ。
441:デフォルトの名無しさん
04/02/11 20:16
うーん.確かに,あんまり使う気は起きないなぁ.
ちょっと残念.
442:デフォルトの名無しさん
04/02/11 23:37
>>438
参考までにほぼ同様のことを Ruby と CLOS で、
class Obj
def m; p "method of " + self.class.name; end
end
obj1 = Obj.new
obj1.m => "method of Obj"
obj2 = Obj.new
obj2.m => "method of Obj"
def obj2.m; p "method *not* of " + self.class.name; end
obj2.m => "method *not* of Obj"
obj1.m => "method of Obj"
obj3 = Obj.new
obj3.m => "method of Obj"
443:デフォルトの名無しさん
04/02/11 23:39
(defclass <obj> () ())
(defmethod m ((self <obj>))
(print
(concatenate 'string
"method for an ordinary " (string (class-name (class-of self))))))
(setq obj1 (make-instance '<obj>))
(m obj1) => "method for an ordinary <OBJ>"
(setq obj2 (make-instance '<obj>))
(defmethod m ((self (eql obj2)))
(print
(concatenate 'string
"method *not* for an ordinary " (string (class-name (class-of self))))))
(m obj2) => "method *not* for an ordinary <OBJ>"
(m obj1) => "method for an ordinary <OBJ>"
(setq obj3 (make-instance '<obj>))
(m obj3) => "method for an ordinary <OBJ>"
444:デフォルトの名無しさん
04/02/12 00:45
Squeak の workspace で無理矢理おなじようなことを。
Object
subclass: #Obj instanceVariableNames: '' classVariableNames: ''
poolDictionaries: '' category: 'Category-Name'.
Obj compile: 'm ↑''method of '', self class name' classified: nil.
obj1 ← Obj new.
obj1 m => 'method of Obj'
obj2 ← Obj new.
obj2 m => 'method of Obj'
obj2 assureUniClass.
obj2 class compile: 'm ↑''method *not* of '', self class name' classified: nil.
obj2 m => 'method *not* of Obj1'
obj1 m => 'method of Obj'
obj3 ← Obj new.
obj3 m => 'method of Obj'
ただし、この時点で、
obj1 class == obj2 class. => false
obj2 class superclass == obj1 class => true
obj1 class == obj3 class. => true
445:デフォルトの名無しさん
04/02/12 02:01
ちなみに Self だとこんなかんじ。
globals _AddSlots: (| obj. obj1. obj2. obj3 |)
obj: (|
name <- 'obj'.
m = (^ 'method of ', parent name) |)
obj1: (| parent* = obj |).
obj1 m => 'method of obj'
obj2: (| parent* = obj |).
obj2 m => 'method of obj'
obj2 _AddSlots: (| m = (^ 'method *not* of ', parent name) |).
obj2 m => 'method *not* of obj'
obj3: (| parent* = obj |).
obj3 m => 'method of obj'
ただしここで obj は、クラス(or トレイト)っぽい位置づけ。
446:デフォルトの名無しさん
04/02/12 03:06
内部的には Python は CLOS に、Ruby は Smalltalk/Squeak の
それに近いのかな…。つまり、CLOS 、Python はインスタンスと
そのクラスとの関係には手を付けずに、注目するインスタンス専用の
メソッドを用意する。これに対して、Ruby (と、まあ Smalltalk/
Squeak)では元のクラスのサブクラスを作って、注目するインスタンス
のクラスをそれに差し替え、インスタンス特異的なメソッドは差し替え
たサブクラスに定義している。
ちなみに Ruby は構文の工夫や、無名クラスを明示的にしないことで、
さもインスタンスにそれ特異的なメソッドを追加できているように
見せかけているので、ユーザーには
447:デフォルトの名無しさん
04/02/12 11:24
どうした >>446 ! 何があったんだ!
どうも concatenate とか本質的でないとこで長くなってる気がするので CLOS 版は
format つかって文字列返すくらいにしといたほうがいいのでは?
(defclass <obj> () ())
(defmethod m ((self <obj>))
(format nil "method for an ordinary ~A~%" (class-name (class-of self))))
(setq obj1 (make-instance '<obj>))
(m obj1) => "method for an ordinary <obj>"
(setq obj2 (make-instance '<obj>))
(defmethod m ((self (eql obj2)))
(format nil "method *not* for an ordinary ~A" (class-name (class-of self))))
(m obj1) => "method *not* for an ordinary <obj>"
かつて Lisp 方面で CLOS ダメポプロトタイプベースイイ! って言ってた連中って
GUI ならプロトタイプのほうが自然だ ! とかプロトタイプベースのほうが速い! とか言っ
てたような記憶があるのです.やっぱ速いんですかね?
448:デフォルトの名無しさん
04/02/12 11:44
>>447
書きかけで送っちゃったけど、意味は通じるからいいかなと(笑)。
format はたしかにそうです。馴染みのないひとにも対応付け易い
よう、冗長にしてみました。ご指摘 & 実例たーしゃ。
ついでに Self も parent* スロットには暗示的にアクセスするので、
こちらも parent name などとする必要はなく、単に name だけに
すべきです。
449:デフォルトの名無しさん
04/02/12 14:33
>>446
> メソッドを用意する。これに対して、Ruby (と、まあ Smalltalk/
> Squeak)では元のクラスのサブクラスを作って、注目するインスタンス
> のクラスをそれに差し替え、インスタンス特異的なメソッドは差し替え
> たサブクラスに定義している。
>
12ヘェ〜。純粋クラスベースOOの枠組み内でうまいことやってるですね。
ちなみにPythonが冗長なのは、滅多に使わないような機能や生産性にほとんど
影響しないようなところに安易に新しい構文を用意することで、言語が無駄に
複雑化したり初心者を混乱させたりするのは悪である、という思想があるから
のようです。ってプロトタイプとかけ離れてきたのでこの辺で。
450:デフォルトの名無しさん
04/02/14 16:30
URLリンク(sof.ch)
> Experimental prototype base object orientation.
Scheme 処理系の一つ、QScheme はプロトタイプベースなオブジェクトシステムを
持ってるらしい。
451:デフォルトの名無しさん
04/02/15 17:36
結構みんなこのスレ見てるんだね。今日だけでも色んなスレでプロトタイプベースという
言葉を見たよ(以前はそうでもなかったけど)。それともプロトタイプベースの認知度が
上がったのかな。
452:デフォルトの名無しさん
04/02/15 20:59
URLリンク(www.logtalk.org)
>Support for both class-based and prototype-based systems
>You may have, in the same application, class-based hierarchies (with instantiation
>and specialization relations) and prototype-based hierarchies (with extension relations).
Prolog のオブジェクト指向拡張ライブラリ? の Logtalk はクラスベースとプロトタイプ
ベースの両方をサポートしているみたい。Features 見ていると、色々面白そう。
453:デフォルトの名無しさん
04/02/15 21:04
で、プロトタイプベースの中で、一番進んだ言語って何?
Ioですか?
454:デフォルトの名無しさん
04/02/15 21:08
ああ、一番遅れた言語ね。
455:デフォルトの名無しさん
04/02/15 21:23
MLud もプロトタイプベースだけど、強型付けな ML 上に構築されているという事は、
MLud 自身も強く型付けされた環境なのかなぁ。だとしたらちょっと異色かも。
URLリンク(moonflare.com)
456:デフォルトの名無しさん
04/02/15 21:36
>>453
言語に大きく依存した機能じゃないから、好きな言語でどうぞっていう流れじゃないかな。
クロージャがあるか、ファーストクラスのメソッドがあれば何とかなる。
457:デフォルトの名無しさん
04/02/16 00:12
>>453
一番進んでいるのはオブジェクトモデル、VMの性能、クラスライブラリ
の充実度のどれをとってもいまだにSelfだろ。ちょっと古いのと、対象
となるプラットフォームが異常に限られているのが玉に瑕だが。
NewtonScript もかなりよくできていたけど、これはプラットフォーム
自体がなくなっちゃったからなぁ…。
目先を変えて、Scheme の SLIB に含まれる YASOS なんかもいいかもしれない。
URLリンク(members.at.infoseek.co.jp)
458:デフォルトの名無しさん
04/02/16 00:20
>>456
インスタンス特異的メソッドのみならともかく、委譲機構をそれなりに
実現しようとすると結構な手間になるのでは?
459:デフォルトの名無しさん
04/02/16 00:55
インスタンスにスロットを持たせるのはなんとなく分かったので、
委譲機構とやらのサンプルコードをキボンヌ。最低限どんな動きが
どれくれーできればいいんだ?
460:デフォルトの名無しさん
04/02/16 02:46
>>459
既出ですが、これなんかよく説明されていると思います。
URLリンク(kumiki.c.u-tokyo.ac.jp)
サンプルコードの書き下ろしは面倒なので勘弁してください。
私自身は、簡単にできるとは思っても言ってもいないので、説明責任もないし(^_^;)。
最低限できればよいのは、委譲先オブジェクトのメソッドを暗示的
(レシーバには見つけられないとき)に、あるいは必要なら明示的 (Self の
resend、Smalltalk 系の super)に起動できて、その際、起動した
メソッドのコード中の偽変数 self には(メソッドホルダではなく)
レシーバを束縛できていること、でしょうか。
461:デフォルトの名無しさん
04/02/17 00:33
459じゃないんだけど。
つまり委譲機構ってのは手前で処理できぬメッセージが来たら
プロトタイプチェーンを遡ってメソッドを探す事っつーことですか。
クラスベースだと何に当たる言葉なんだろう。「ポリもアフィズム」じゃないし。
self / this にそもそもメッセージを受けた人が入らないといけないが、
クラスベースなら[[クラスの]]継承階層を遡っていき、クラスとオブジェクトが峻別されるから
あまり問題にならないところだが、
プロトタイプベースだと[[オブジェクトの]]チェーンを遡っていくんだが
でも親のオブジェクトが受けちゃったりしたらまずいって訳だ。
RubyもSelfもわからんので読めん。
漏れの読めるプロトタイプベースはECMAScriptだけでいいや・・・。
462:n
04/02/17 10:11
本当にECMAScriptってプロトタイプベースなんですか?
わたしにはろくに継承/委譲ができないように思えるのですが・・・。
463:デフォルトの名無しさん
04/02/17 16:56
>>462
勉強を兼ねて恒例の bank account を書いてみました。
委譲/継承も多態もできているみたいです。
個人的には self をメソッドで暗示的引数に指定しなくていいぶん、
Python よりはスジがよいように思います。
<script type="text/javascript">
var bank_account = new Object;
function ba_set_balance(_x) {this.balance = _x; return this}
bank_account.set_balance = ba_set_balance;
function ba_get_balance() {return this.balance}
bank_account.get_balance = ba_get_balance;
document.write( bank_account.set_balance(200).get_balance() + "<br>"); // => 200
function ba_deposit(_x) {
this.set_balance(this.get_balance() + _x);
return this}
bank_account.deposit = ba_deposit;
document.write( bank_account.deposit(50).get_balance() + "<br>"); // => 250
function ba_withdraw(_x) {
this.set_balance(Math.max(this.get_balance() - _x, 0));
return this}
bank_account.withdraw = ba_withdraw;
document.write( bank_account.withdraw(100).get_balance() + "<br>"); // => 150
document.write( bank_account.withdraw(200).get_balance() + "<br>"); // => 0
464:デフォルトの名無しさん
04/02/17 17:05
>>463 続き
var my_account = new Object;
my_account.__proto__ = bank_account;
document.write( my_account.set_balance(100).get_balance() + "<br>"); // => 100
document.write( my_account.deposit(50).get_balance() + "<br>"); // => 150
document.write( bank_account.get_balance() + "<br>"); // => 0
465:デフォルトの名無しさん
04/02/17 17:07
>>464 続き
function sa_set_num_shares(_x) {this.num_shares = _x; return this}
stock_account.set_num_shares = sa_set_num_shares;
function sa_get_num_shares() {return this.num_shares}
stock_account.get_num_shares = sa_get_num_shares;
function sa_set_price_per_share(_x) {this.price_per_share = _x; return this}
stock_account.set_price_per_share = sa_set_price_per_share;
function sa_get_price_per_share() {return this.price_per_share}
stock_account.get_price_per_share = sa_get_price_per_share;
stock_account.set_num_shares(10).set_price_per_share(30);
document.write( stock_account.get_num_shares() + "<br>"); // => 10
document.write( stock_account.get_price_per_share() + "<br>"); // => 30
466:デフォルトの名無しさん
04/02/17 17:10
>>465 続き
function sa_set_balance(_x) {
this.set_num_shares(_x / this.get_price_per_share());
return this}
stock_account.set_balance = sa_set_balance;
function sa_get_balance() {
return this.get_num_shares() * this.get_price_per_share()}
stock_account.get_balance = sa_get_balance;
document.write( stock_account.get_balance() + "<br>"); // => 300
document.write( stock_account.set_balance(600).get_balance() + "<br>"); // => 600
document.write( stock_account.set_balance(600).get_num_shares() + "<br>"); // => 20
document.write( stock_account.deposit(60).get_balance() + "<br>"); // => 660
document.write( stock_account.get_num_shares() + "<br>"); // => 22
document.write( stock_account.withdraw(90).get_balance() + "<br>"); // => 570
document.write( stock_account.get_num_shares() + "<br>"); // => 19
</script>
次ページ最新レス表示スレッドの検索類似スレ一覧話題のニュースおまかせリスト▼オプションを表示暇つぶし2ch
5405日前に更新/368 KB
担当:undef