トップページ⇒tech
1001コメント296KB

Rubyの実装に疑問あり!

■ このスレッドは過去ログ倉庫に格納されています
0001「真面目な」反対派(何が真面目なのか知らないが)NGNG
Rubyの実装は、バイトコード使用ではなく、
構文木をeval関数(巨大なswitch文)でたどっていく方法だが。
これでは速度的に不利だ。
また、そのせいで例外処理にsetjmpとlongjmpを使う風になっていて、
余計な負担がかかっている。
GCもスタックを勝手にサーチして「保守的ごみ集め」をやっているが
これも速度的に問題がある。
開発者のまつもと氏はいったいどう考えて作っているのか、
知りたいところだ、、、。
0232デフォルトの名無しさんNGNG
メタクラスって、
クラス自体もオブジェクトだと看倣した時に
その「クラス」オブジェクトのクラスは何かって考えると
わかりやすいよ。
ただし、クラスについて考える時に
例えばIntegerなら
Integerという名前のオブジェクトか
Integerクラスのオブジェクトか
をきちんと区別しないと混乱するから注意。

ちなみにSmalltalkでは
1
-> SmallInteger
-> SmallInteger class(SmallInteger classはClassのサブクラス)
-> Metaclass
-> Metaclass class(Metaclass classはClassのサブクラス
-> Metaclass
以下無限に続く
っとなっとりますです。
ついでにクラス階層は
-Object
- Behavior
- Metaclass
- Class
- Object class
- Behavior class
- Metaclass class
- Class class
- Magnitude class
- Number class
- Integer class
- SmallInteger class
- Magnitude
- Number
- Integer
- SmallInteger
0233厨房質問NGNG
で、結局メタクラスって実用上どんな時に役立つの?
>>231の言ってることは解るけど、内部の仕組みをわざわざ言語仕様として
ユーザーに扱わせるからには何か利点があるんだと思うけど。
0234デフォルトの名無しさんNGNG
>>233
まずクラスをオブジェクトとして扱うのなら、
そのクラスのクラスが必要になるってのはOK?
0235232NGNG
やっぱ崩れた...欝だ...
0236226NGNG
226だ。ありがとよ。

なるほど。だんだんわかってきたような気がする。
要するにメタクラスというのは、「動的」つまり実行時に、クラスの情報を取得したり、
クラスを操作したりするために存在するものなのだろう。
そして、クラス−インスタンス関係は

インスタンスオブジェクト --> 通常のクラス --> メタクラス

となる。
以上が俺の理解した「メタクラス」の一般だ。間違っているかもしれんが。

ここで、Rubyのクラス継承図
http://www9.xdsl.ne.jp/~aamine/ja/ruby/hack/class.html
を見ると、Objectを含む通常のクラスはそれぞれメタクラスを持っている。
メタクラス間にも通常のクラスと同様の継承関係がある。
だからメタクラスの根っこ(何て言うんだ?)は、Objectのメタクラスとなる。
ところで、この根っこのObjectのメタクラスは、通常クラスのClassから継承されている。
このClassにクラス操作のメソッドが存在するのだろう。
ということは、このClassは「メタメタクラス」ということになるのだろうか。
Classは通常のクラスなので、Objectから継承されている。
(このことによって、ClassはObjectの性質を持つ)
そして、そのObjectはメタクラスObjectのインスタンスであるから、
(スーパークラスである)Classの性質を持つ。
ということになるのだろうか。

これも間違っているだろうか。それ以前に説明が下手だったかもしれんが。
なんだか、「メビウスの輪」のように循環しているような部分があるからな。ObjectとClassの間で。
しかし、要するにそれは、全てのクラスを動的に操作可能にするための仕掛けなのだろうか。
つまり、誰かが言っていたように、全てをオブジェクトとして扱う、とか。

しかし、、、。
>>228
>余談だけど、クラスのメタクラスClassはClassのインスタンスでもあるらしいんだけど、、、
>こう言うのを考えるともっと混乱してくる思うので、気にせずに逝こう!
やっぱ、わかんなくなってきた。
もちろんメタクラスのことを考えなくとも、Rubyを使うことは可能だろうが、何か気になってすっきりしねえ。
0237デフォルトの名無しさんNGNG
>>233
メタクラスがあると、クラスも他のオブジェクトと同じように扱える。
返り値でクラスを返したり、変数にクラスを入れたりできるってこと。
0238デフォルトの名無しさんNGNG
>>236
ObjectとClassの間で循環しているってのはイイ線ついてる。
ただ、

> ところで、この根っこのObjectのメタクラスは、通常クラスのClassから継承されている。
> このClassにクラス操作のメソッドが存在するのだろう。
> ということは、このClassは「メタメタクラス」ということになるのだろうか。

継承関係とメタ関係を混同しているような...
Hogeというクラスがあったとして、
(Hoge)が(Object)から継承しているということが
(Hoge)のメタが(Object)だというわけではない。
それは、
HogeがObjectから継承していても
HogeのメタがObjectじゃないのと同じ。
Hogeのメタは(Hoge)だよね。

Rubyはよく知らないけど、もし
「ClassはClassのインスタンスでもあるらしい」が本当なら
(Hoge)のメタはClassという通常クラスで、Classはメタメタクラスになる。
ただ、これは継承関係とは全く別の話。

例えばSmalltalkだと
hogeのクラスはHogeで
Hogeのクラスは(Hoge)で
(Hoge)のクラスはMetaclassで、かつ、(Hoge)はClassのサブクラスで
Metaclassのクラスは(Metaclass)で
(Metaclass)のクラスはMetaclass
ってなってる。
つまり(Hoge)をメタクラスと呼ぶのは
「(Hoge)はMetaclassのインスタンスである」という意味。
これは1は整数と呼ぶのは
「1は整数のインスタンスである」ってのと同じ。
メタクラスの話をするときは、「1」と「整数」の混同に気を付けないと
わけわからなくなるから注意。
0239238NGNG
> (Hoge)が(Object)から継承しているということが
> (Hoge)のメタが(Object)だというわけではない。
じゃなくて
> (Hoge)がClassから継承しているということが
> (Hoge)のメタがClassだという理由ではない。
ね。スマソ。
0240デフォルトの名無しさんNGNG
長い→読まない
0241デフォルトの名無しさんNGNG
「長い→読まない」→読まない
0242デフォルトの名無しさんNGNG
はっきり言ってわざと難解に書いているのかと思う。
0243デフォルトの名無しさんNGNG
世の中、一言で簡単に説明できることばかりではない。
0244デフォルトの名無しさんNGNG
SmalltalkのMetaclassのあたりはグチャグチャで汚らしいよね。
なんでMetametaclass、Metametametaclassがなくて、ClassとMetaclass
の2段だけなのか? 答:特に理由はない。
なんでいっそJavaみたいにClassだけにしなかったのか? 答:特に理由はない。

自分自身を(間接的に)要素に持つ集合なんて言うのを安直に考えた型システ
ムは健全でなくなるが、ちゃんと考慮されてるのか? 答:深く考えてない。
0245デフォルトの名無しさんNGNG
>>244
再帰的に考えられないの?
CLOSとかのシステムはmetaclassの生成対象がmetaclassに
なることもある。
0246デフォルトの名無しさんNGNG
244 はコボラー
0247228NGNG
なんか、僕の所為で混乱している人が多数、、、
僕が言った、メタクラスというのは、プログラミング上で実際、
そのオブジェクトのクラスに見えるクラスのことであって、
実装におけるklassが示すクラスの事じゃなかったんだけど、、、
と言うことで、用語が混乱しておかしかったと、、、すいません。

RubyではClassのクラスはClassだよ。
klassが示すものとしてのメタクラスの意味ではClassのメタクラスは(Class)だけど。

class Hoge; end
hoge = Hoge.new
hoge.type #=> Hoge
Hoge.type #=> Class
Class.type #=> Class

ってね。
0248デフォルトの名無しさんNGNG
>>244
MetaclassがあることによってClass操作の柔軟性が増す。
同様にMetametaclassによってMetaclassの操作も可能にしたいと考えるが、
それを認めてしまうと無限のメタを許容することにもなってしまう。
そこで、全ての基底クラスにObjectを置き
作る作られるの関係を重視してMetaclass/Classという形にした、という話では?
プロトタイプ型の言語でプロトタイプの一種としてクラスの概念を導入した
と考えれば納得のいく構成だと思う。
0249デフォルトの名無しさんNGNG
Metaclassだってクラスなんだから、Metametaclassなんて要らないんじゃないの?
Metametaclass=Metaclassで不都合なかろう。
>>244で、”スモールトークでは”って書いてあるのがきになるんだが、本当にこのことが問題になってたんですか?
0250デフォルトの名無しさんNGNG
っていうか、
メタクラスの概念についてはいろいろ説明してる文章もあるけど
SmalltalkのClass,Metaclass周りのsource以上にわかりやすいものは
見たことないんだよね、正直言って。
つまり、
Metaclass自体がSmalltalkでどれだけ役に立ってるかというより、
OOにおけるメタ階層という概念の提示として
とても歴史的な意義があるんじゃないかと思う。

rubyなりpythonなりのメタ階層を設計する上で、
SmalltalkのClassやMetaclassは参照標準として
かなりの貢献をしたんじゃないかと思うよ。
0251厨房質問NGNG
これまでで
>>234 >>237 等
メタクラスの概念でクラスをオブジェクトとして扱えるのは
解ったんだけど、
それが実用上どんな利点をもたらすんでしょ?
人工知能で自己書き換えでもするんなら役立ちそうだけど。
0252デフォルトの名無しさんNGNG
>>251
動的なコード生成で使える。
XML文書を読み込んでオブジェクト化する時とか。
0253デフォルトの名無しさんNGNG
>>251
Smalltalkなんかだと、Smalltalkの開発環境もSmalltalkで
書かれているから、クラスをオブジェクトとして扱える事は
死活問題にかかわる。まさに自己書き換えの世界。

それ以外では、うーん、
例えばカラーパレットを実装したいとするよ。8bppとか24bppとか。
で、ColorPaletteという抽象クラスを作っておいて、
そのサブクラスにIndexedColorPaletteとRGBColorPaletteがあるとする。
で、8bppか24bppか32bppかに応じて使うクラスを切り換えたいと。
で、そんな場合は、それぞれのクラスにcanHandle()っていうメソッドがあって、
引数として8とか24とかのbppを与えると、trueかfalseを返してくれるようにする。
で、ここからがミソなんだけど、ColorPaletteクラスもオブジェクトだから、
「ColorPaletteの全サブクラスのそれぞれにcanHandle()を試してみて、
trueを返す」ようなメソッドを定義できる。
そしたら、その返ってきたクラスを使ってインスタンスを作ればいい。

クラスがオブジェクトじゃなくても似たような動作をさせる事は可能だけど、
サブクラスの名前をハードコーディングする事になると思う。
クラスがオブジェクトなら、サブクラスを追加した時にも
その追加したクラスのcanHandle()さえちゃんと定義しておけば
ColorPaletteクラスには手を入れる必要はない。
例えばBlackWhitePaletteとかMaskとか追加する時ね。

ってのはどうでしょう? >>251
0254win530NGNG
win530
0255253NGNG
欝だ...
「ColorPaletteの全サブクラスのそれぞれにcanHandle()を試してみて、
trueを返す」ようなメソッドを定義できる。
は
「ColorPaletteの全サブクラスのそれぞれにcanHandle()を試してみて、
trueを返してきたクラスを返す」ようなメソッドを定義できる。
の間違いね。
欝になったから寝るよ。
0256デフォルトの名無しさんNGNG
smalltalkのコアの部分の実装ってどれぐらい大変ですか?
コアよりもライブラリの構築が大変そうだけど。
0257デフォルトの名無しさんNGNG
>>256
↓資料。
http://minnow.cc.gatech.edu/squeak/1602
0258厨房質問NGNG
>>252-253
レスありがとう。
俺的には、メタクラスの存在は現状ではユーザー側からは
限定的な状況でしか役に立たないと解釈しました。

実用上でこれまで主流だったのが非インタプリタ・非VMな
言語だったから、今実用されているアルゴリズムやデータ構造に
目立って役立たないのも当然の事なのかも?
0259デフォルトの名無しさんNGNG
>>71
今の gcc は bison/flex つかわないで手書きパーサだったはず。
0260デフォルトの名無しさんNGNG
>>253
>クラスがオブジェクトじゃなくても似たような動作をさせる事は可能だけど、
>サブクラスの名前をハードコーディングする事になると思う。

要するにSmalltalkではそういう時に使われるメタ情報が
(C++などでは最適化ビルド時に全部削除されるにも関わらず)
くっついているので、いわばサブクラスの識別子が最初から
ハードコーディングされているだけでしょ。そのことから
生じるデメリットも挙げなければミスリーディングだと思う。
0261デフォルトの名無しさんNGNG
>>258 >>236
標準ライブラリのdelgate.rbにあるDelegateClass見てみろ。メタクラスが役に
たってる例だ。C++だったら、templateやマクロでアクロバット的なことをする
ような場合に、クラスがオブジェクトだと素直に書ける。
0262デフォルトの名無しさんNGNG
>261
でも限定的なのは確かだよね・・・。
0263デフォルトの名無しさんNGNG
>>260
「いわばサブクラスの識別子が最初からハードコーディングされている」
ってどういう意味よ?
#スーパークラスが持っているのはサブクラスへの参照だけで
#名前なんて保持してないはずだが...
0264デフォルトの名無しさんNGNG
>>250
新しい言語はRubyもJavaもメタクラスなんて使ってないんだから
結局不要だったって事じゃないの?それがSmalltalkの教訓かも。

なんで「ClassとMetaclassの2段だけのループ」が良いのか、って
いうのが結局説得力のないad hocな話だったってのがわかってきた
ので「Classだけの1段のループ」でみんな満足してるんでしょう。
0265デフォルトの名無しさんNGNG
>>263
smalltalkバイナリの大きさを見よ
0266デフォルトの名無しさんNGNG
>>264
…
0267デフォルトの名無しさんNGNG
>>265
で、Smalltalkのvirtual imageのうち
ハードコーディングされているサブクラスの識別子が
占めているサイズは何割ぐらいなのさ? (藁
0268デフォルトの名無しさんNGNG
>>264
だとすると、
shもEmacs Lispもオブジェクト指向を取り入れてないから
オブジェクト指向は不要なんだね (藁

用途からして全く違う言語を持ち出して、不要も何もないぞ。
Rubyはスクリプト言語だからMetaclassがオブジェクトじゃないのは理解できるし、
Smalltalkはそれ自身が開発環境だから、Classのクラスがオブジェクトなのは
とても自然な事だろ。
0269デフォルトの名無しさんNGNG
>>268
「shやEmacs Lispにとっては」オブジェクト指向は不要です。
もしかしてshにオブジェクト指向が必要だと思ってるとか?
もう寝ろ
0270322NGNG
>>268
>Rubyはスクリプト言語だからMetaclassがオブジェクトじゃないのは理解できるし、
えっ?そうだっけ?
というより、Metaclassという名前のクラスRubyには無いんだけど、、
というより、Rubyのメタクラスもオブジェクトのはずなんだけど、、
つか、Rubyのメタクラスは普通隠されているから、気にするなって、、、
全てのクラスのクラスはClassって思っていればだいたいいいのに、、、
0271デフォルトの名無しさんNGNG
>>268
何を言ってるのかワカランが(本人もワカランのかも知れんが)
RubyだってJavaだってClassのクラスはオブジェクトだぞ。

開発環境をその言語自身で書く時だって特に不都合はなかろう。
0272271NGNG
一行追加: メタクラスなんか無くったってな。
0273デフォルトの名無しさんNGNG
Lisp や Java や Ruby のメタクラス的概念の
おかげで自己反映計算ができるんだよね?
0274デフォルトの名無しさんNGNG
スマートに記述できるという意味ではね。一般にはあまり使い道はないけどね。
0275デフォルトの名無しさんNGNG
>>273
CLOSにはMetaclassがあるが、JavaやRubyにMetaclassの概念はない。
(無くても自己反映計算はできる。)
0276デフォルトの名無しさんNGNG
>>236
>なんだか、「メビウスの輪」のように循環しているような部分があるからな。ObjectとClassの間で。

私もメタクラスとあのクラスツリーでつまづきました。
newなどのメソッドはClassにあるらしいですが、
そのnewのメソッド検索の順序はどうなるのでしょう?

class A end
var1 = A.new

例えば、上記のコードの場合、
クラスA→Object→Objectのメタクラス→Class
という順にクラスツリーをたどって、メソッドテーブルが検索されていくのでしょうか?それとも?

Rubyのソースは、Perlよりも比較的、初心者にもわかりやすいと思うのですが、このメタクラスやクラスツリーに関するところ
は私などにはかなり難解です。
0277デフォルトの名無しさんNGNG
>>276
メタクラスは()で囲んであらわすよ。
メタクラスは得意クラスなのでプログラマからは見えない(typeでクラスを調べるときスキップされるなど)から注意してね。
で、オブジェクトとクラスの関係は"=>"でサブクラスとスーパークラスの関係は"→"であらわします。
class A; end
var = A.new
は
A => (A) → (Object) → Class
で、Classのnewが呼び出されるって事になります。
また、普通のオブジェクトであれば、、、
a = A.new
a.__id__
は
a => A → Object
で、Objectの__id__が呼び出されることになります。
で、特異メソッドとかは、、、
class <<a
  hoge(); end
end
a.hoge
a.__id__
は
a => singleton → A → Object
で、singletonのhogeとObjcetの__id__が呼び出されます。
singletonは無名の特異クラスなので同じくtypeなどではスキップされます。
つまり、メタクラスは特異クラスであり、クラスメソッドはメタクラスの特異メソッドであるわけで、プログラム上のクラスはClassと考えてもいいと思います。

RubyはPerlよりも簡単とか言われてますが、それはオブジェクト指向を理解している人には簡単だという事に、最近僕には思えるのですが、、、
そう言う意味ではオブジェクト指向を理解する為にRubyを学ぶことはいいことかも知れませんね。
0278デフォルトの名無しさんNGNG
なんかゴチャゴチャして汚らしいね。
「隠れたメタクラス」なんてどうせ使わないんなら
無くした方が速度も速くなるだろうに。
0279デフォルトの名無しさんNGNG
>>277
Rubyのメタクラスってどんなメソッドがあるの?
newをredefineしたりメソッドの呼び出し方をいじったりできるの?
できないならメタクラスがある意味はないな。
0280デフォルトの名無しさんNGNG
>>279
できたってたいした意味はないよ。
メタオブジェクトプロトコルを変えるにはどうするんだ?
メタメタクラスがいるだろう? でも、そんなのはSmalltalkにもない。
0281デフォルトの名無しさんNGNG
>>280
Smalltalkにもないってヲイヲイ...
Metaclass(という名前のクラス)がまさにそれだろ。
0282デフォルトの名無しさんNGNG
>>278
じゃ、隠れたメタクラスを使わずにクラスメソッドをどう実装するんだ?
クラスメソッドを特異メソッドと同様なものとして扱える
うまい実装だと思うが、、、

>>279
newの再定義はできるよ。
まあ、一般に使うことはないと思うが、、、
(どのようにnewが動いているか調べることぐらいしか使えないと思う。)
0283デフォルトの名無しさんNGNG
>>282
278は実装の話はしてないと思われ。
滅多に使わない機能なんか言語仕様から外しちまった方が
処理系の効率があがってマンセーだと言いたいのでは?
漏れは大して変わらないと思うがな。今の仕様に取り込まれているのは
作者の趣味だろ(藁
0284デフォルトの名無しさんNGNG
>>276
>Rubyのソースは、Perlよりも比較的、初心者にもわかりやすいと思うのですが
自分もそう思った。
言語としての善し悪しは知らないが、こと、ソースの可読性、読みやすさに関しては
間違いなくRubyの方が上だと思う。

以前Perlのソースを読もうとしたのだが、すぐ挫折した。
オライリーの青い背表紙の本のどれだったかを立ち読みして、
ようやくスカラやハッシュなどのオブジェクトが2段、3段がまえになっているらしいと知った。
けど、あの本読んでも、ほとんど理解できなかったな。

Rubyのオブジェクトは、VALUE(u_long)の最下位ビットがゼロならRStringなどのオブジェクトへのポインタで、
そうでなければFixnum(Small Integer)などの値であるからわかりやすい。
自分でもインタプリタ(といっても簡易なものだが)を作った時、Rubyを参考にした。

どちらがより良い実装かなどはわからないが、
確かにPerlのソースは、初心者には難解だと思う。
0285デフォルトの名無しさんNGNG
話しはかわるんですが、IPAの未踏ソフトウェアは1年だけだったんですか?
今年度は名前がみあたりません。
0286デフォルトの名無しさんNGNG
>>281
Metaclassのメソッド(メタオブジェクトプロトコル)を「使う」
ことと、メタオブジェクトプロトコルを「変える」ことをごっちゃに
してないか?メタオブジェクトプロトコルを「変える」にはもう一段
メタがいるだろう、という話をしてるんだが?

>>282
ユーザーから見える言語仕様上、Rubyにメタクラスはないと言って
良いんじゃないの?実装上の都合(趣味)は知らん。プログラマから
見えなくて良いなら、OO的に書く必要もない。Java風にでもC++風に
でも、効率良いようにやれば良いんでは?
0287デフォルトの名無しさんNGNG
>>286
まったく見えないわけでもないんだがな。

module Kernel
 def iclass
  class << self
   self
  end
 end
end

しかしメタクラスと中間クラスを混同しないように。
RubyのClassがメタクラス。中間クラスは実装の都合上の存在。
0288PythonNGNG
>>287
このendendendendが不恰好なんだよな・・・
0289デフォルトの名無しさんNGNG
どうせやるんならさ、VBみたく
end class
とかのほうが良かったんじゃない?
はっきりいって読みにくいよ。
0290デフォルトの名無しさんNGNG
読みにくさは我慢するけど、そういう実装にして速くなったの?
0291デフォルトの名無しさんNGNG
>>284
スレ違いですが
PerlにはRubyHacker'sGuideのような、ソースに即した解説は
ないのでしょうか?
0292デフォルトの名無しさんNGNG
>>288
ここでインデントがどーしただの言ーだすと
また無意味な闘争が起こるんだろうな、、、。
お互い、そーゆの、やめよー。
0293デフォルトの名無しさんNGNG
>>292
スクリプト言語にとっては本質的な問題だと思うぞ。
0294デフォルトの名無しさんNGNG
スレ違い
0295デフォルトの名無しさんNGNG
>>292
それだけ目に付くついうことだな。
実際、>>287のソースはインデントでかろうじて意味を
保っている様に感じる。
0296デフォルトの名無しさんNGNG
{}でない理由がわからん。
0297デフォルトの名無しさんNGNG
>>288、>>293、>>295、>>296
292と294の言うとおりスレ違いだと思う。
これは、Rubyに限った話ではないし、、、
「{}、end、インデントのみ、どれが一番いいんだ?」
みたいな、別スレを立ててそこで議論すべし、、、
#不毛な議論になりそうだけど、、、
0298デフォルトの名無しさんNGNG
C-like
module Kernel{
 def iclass{
  class << self {
   self
  }
 }
}
LISP-like
(module Kernel
 (def iclass
  (class << self self)))
VB-like
module Kernel
 def iclass
  class << self
   self
  end class
 end def
end module
0299デフォルトの名無しさんNGNG
で、昔Python-likeが一番って結論になったんだよな。
Python-like。

module Kernel
 def iclass
  class << self
   self
0300デフォルトの名無しさんNGNG
>>299
字下げで有効範囲を決めるのをPython-likeなんていうなよ。
Oberonの方が早いだろ。Haskellだってそうだし。
0301デフォルトの名無しさんNGNG
>>300
ならC-likeとVB-likeについても同様。
0302デフォルトの名無しさんNGNG
Cだって、1行の字下げはある。
0303デフォルトの名無しさんNGNG
>>284
最近になって、まつもとさんとPerl開発者の一人の間接的な
対談記事を読みました。
Perl開発者から、なぜ構文木を長大なswitch文(rb_eval)で
たどって解析する方法をとったのかと、そんな意味のことを
訊ねられていたと思います。
それに対して、まつもとさんはPerlのように構文木のノードに
関数ポインタを埋め込む方法を試したが、思ったより速度が
上がらなかったと答えていたと思います。
(もちろん、自分の実装コードがまずかったのもあるだろうとも
言っていました)

僕はこの記事で初めてPerlの構文木とその評価方法を聞きました。
それまで、Rubyのソースしか見たことがなかったので。
僕も以前、インタプリタ型の小さな言語をRubyを参考に作りました。
オブジェクトやスタックフレームなど、大いに参考になり助かった記憶があります。
ただ、僕も構文木の評価、つまり解釈実行のルーチンだけは
長大なswitch文を使うのはどうかと迷いました。
結局、C++で書いていたので、構文木のノードの基底クラスに
virtual な評価関数をおくことにし、派生クラスの方の評価関数で
それぞれのノードに応じた処理をする、ということにしました。
下記のように。(まちがいがあるかも。擬似コードとして見てやってください)

しかし今考えると、下手くそなやり方だったと思います。
もっと良いやり方はなかったかと、、、。

class Node {
public:
virtual Value Eval( Node * ) = 0;
};

class NodeAdd : public Node {
public:
Value Eval( Node *node ) {
l = Eval(node->left);
r = Eval(node->right);
return l + r;
}
};
0304デフォルトの名無しさんNGNG
アホですか?素直にジャンプテーブル使えや。
0305303NGNG
すみません、上の記事のアドレスは下記です。
http://www-6.ibm.com/jp/developerworks/linux/001027/ruby_qa.html
「宝石たちの語らい
Perl開発者 Simon Cozens氏から、Ruby開発者 まつもと ゆきひろ氏への質問とその回答」

すでに多くの方は読んでいるのでしょうが、、、。
0306303NGNG
>>304
すいません、厨房でした。
ただ、C++覚えたてで、仮想関数が使ってみたかったのです、、、。
0307デフォルトの名無しさんNGNG
>>306
まつもと氏に言ったのだ。

構造化からON_GOTO外したのは間違いだなー。
0308デフォルトの名無しさんNGNG
>>303
その記事は読みました。
matzも言っていますが、最近のコンパイラは最適化に優れているので、switch文の分岐はかなり高速になっていますから。

趣味や学習でつくったのなら構わないとは思います。
ただ仮想関数を使うと遅くなるでしょう。
0309デフォルトの名無しさんNGNG
>>308
何をえらそーに。
0310デフォルトの名無しさんNGNG
>>309
お前だよ、それ。
0311デフォルトの名無しさんNGNG
このスレもいよいよ、つまんなくなってきたな。
0312デフォルトの名無しさんNGNG
Rubyの実装に疑問あり! ×
Rubyの存在に疑問あり! ○
0313デフォルトの名無しさんNGNG
Rubyの存在に疑問あり! ×
Rubyの存在に感心なし! ○
0314デフォルトの名無しさんNGNG
Rubyの実装に疑問あり! ×
HSPの実装に疑問あり!  ○
0315デフォルトの名無しさんNGNG
Rubyの実装に疑問あり! ○
Rubyの存在に疑問あり! ○
Rubyの存在に明日なし! ○
0316デフォルトの名無しさんNGNG
JAVAの存在の方が明日なし! ○
0317デフォルトの名無しさんNGNG
Mindに未来無し。今も無し。 ○
0318デフォルトの名無しさんNGNG
このスレも終わったな。
もう書かんでいいぞ。
0319デフォルトの名無しさんNGNG
とか言いつつageる>>318は
書くなと言われると書きたくなる人(オレモナー)に
書かせようとしているに30ruby
0320デフォルトの名無しさんNGNG
           ∧ ∧ ∧ ∧  ∧ ∧ ∧ ∧
  ∧ ∧     /(,,゚Д゚) (, ゚ρ゚) (, ゚ω゚) (*゚д゚) ̄⌒ヽー
  (, ゚д゚)⊃┳━∪∪━∪∪━∪∪━∪∪━⊂∪━┳ ΛΛ
 ヽ/   | . ┃  このスレは終了しました!      ┃(゚д゚;)_、
 (__∪  ). ┻━━━━━━━━━━━━━━━━┻ `uuuu
 ゙゙゙゙゙゙゙゙゙゙゙                             ゙゙゙゙゙゙゙゙゙
↓↓↓新スレはこちら↓↓↓
http://game.2ch.net/test/read.cgi/gamedev/1005313791/
0321デフォルトの名無しさんNGNG
どうでもいいけど大きなswitchってコンパイルすると
ジャンプテーブル使ったコードになるよね。
0322デフォルトの名無しさんNGNG
Cでそれ以外にジャンプテーブルってどう書くの?
関数へのポインタ配列?(遅そう…)
0323デフォルトの名無しさんNGNG
何で遅いの?
アドレスロード+callだけじゃん。
0324デフォルトの名無しさんNGNG
このスレ終わり、書かんでよろし。
新スレはPerl実装。
0325デフォルトの名無しさんNGNG
>>323
CPUのプリフェッチ/パイプライン処理を詰らたりはするがな (藁
0326デフォルトの名無しさんNGNG
>>305
だいぶ昔の記事だな。
まつもとの言うこと、あてになるのか?
0327デフォルトの名無しさんNGNG
>>325
それは、ジャンプテーブルじゃなくてフラットなコードに展開しろってこと?
そんなことしてる処理系は存在しないだろ
0328デフォルトの名無しさんNGNG
          / ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄
          | こ、このスレ さ、さむいモナ〜
   Λ_Λ  ∠_____________
  (;´Д`)
 ( ( つ ⊂ ))
   〉 〉く く
( (__)(_.)) ...ガクガク
0329デフォルトの名無しさんNGNG
callしたらreturnもしなきゃいけないんだよ。まずそのぶんjumpより遅くなる。

switchと違って局所変数を共有するわけには行かないから、インタプリタのス
タックポインタなんかは大域変数を使うか、引数で渡さなきゃなんない。
switchだとレジスタを見れば良いだけだった場合でもね。

レジスタに変数が割り当てられてたら、Cのコンパイラはレジスタをいちいち
退避/復帰するコードを出すだろうし。
0330デフォルトの名無しさんNGNG
tail call セヨ。
0331デフォルトの名無しさんNGNG
>>330
ワラタ
一回飛んだら戻らないのか。
それともSchemeで書くのか?
■ このスレッドは過去ログ倉庫に格納されています