Ruby前回のKawasaki.rbでいつものパーフェクトRubyの読書で、下のような感じのコードがサンプルとして出てきた。定数にClass.newの結果を代入すると、その定数名をクラス名とするクラスが定義される機能を初めて知った。Rubyのバイトコードをちょっと覗いてみたいのもあり、Rubyとmrubyについて、どんな風にバイトコード上で表現されるのか、確認してみた。MyClass.newo.helloこのコードを実行してみると。以下のような出力がされる。KonnichiwaKonnichiwaHelloRubyのバイトコードこちらは、Rubyのバイトコード。https://qiita.com/nownabe/items/47cc5d95e8b4e01205a8を参考にして、次のようなコマンドで出力した。mrubyのバイトコードこちらは、mrubyのバイトコードです。mrbcにverboseオプションをつけると出力できる。バイトコード読んでみるmrubyのバイトコードを参考に、Rubyのバイトコードを読んでみる。自分用のメモなので、わかりにくいのは承知で、だらだらと書き連ねてみる。Rubyのバイトコードをちゃんと見たのは初めてだけど、mrubyで読んでいたので、なんとなく内容は理解できた。理解するため、Rubyのしくみをちゃんと最後まで読まねば、と思った。mrubyのVMははレジスタマシンだが、RubyのVMはスタックマシンなので、オブジェクトをスタックに積んだり、取り出したりして、処理が行われる。Class.newを用いたクラスの定義getconstantで、:Classというシンボルに対応する定数。Classクラスのインスタンスをとってきて、それをレシーバとして、send(:new,block)しているようだ。定数名がクラス名に化ける仕組みは、見てみるとsetconstantで:MyClassというシンボルを名前とする定数を定義して、それに対してClass.newの結果を代入している。クラスオブジェクトも結局は定数であるので、定数に代入するだけで、クラスとしての名前付けと行わなくても、クラスオブジェクトとして使えていると理解した。mrubyの場合は、newメソッドの戻り値(R3)を、OP_SETCONSTで設定した定数"MyClass"に代入している。この流れはRubyと同じようだ。クラスを定義するブロックブロックの中身は、通常のクラス定義と同じような処理になっていて、defでは、実際には、iseqを引数にdefine_methodメソッドを呼び出す処理になっている。対して、mrubyでは、OP_LAMBDAと、OP_METHOD命令でメソッドを定義している。mrubyでirepに相当するのが、iseqと思えばだいたいよさそう。endなどといっしょに実行される。クラスを定義するブロックの中での外部オブジェクト参照もう一つ気になっていたのは、Class.newにブロックを引数として渡すと、その中でクラスの定義を行えるという処理と、ブロックであるので、クラス定義の途中で外のオブジェクトを参照できるという点。バイトコード上でどう実装されているか見てみる。1としてローカル変数から取得して使用されている。send(:new)したときに、ローカル変数のスコープが引き継がれている、ということみたい。詳しくはsendの処理を更に理解する必要があると思われる。mrubyの場合は、OP_GETUPVARで呼び出し元にレジスタをさかのぼってピンポイントで参照している。コンパイラが頑張っていることが伺える。まとめRubyとmrubyで、Classクラスを使った処理をバイトコード上で、比較してみた。スタックマシンとレジスタマシンの違いはあるが、内容は結構似ていた。ブロックのスコープの扱いについては違いが大きそうなので、もう少し調べてみたい。ここまで触れていないが、Rubyのバイトコード命令中のspecialobjectが何なのかよくわからなかった。ささだんの過去の連載↓には出てきていないので、あとで追加されたもののようだ。直近の体外的な活動予定を記載しています。...技術書典7でESP32とmruby関連の新刊出します技術書典7もいよいよ明日になりました。コメントをキャンセルメールアドレスが公開されることはありません。*ウェブサイト次回のコメントで使用するためブラウザーに自分の名前、メールアドレス、サイトを保存する。上に表示された文字を入力してください。直近の体外的な活動予定を記載しています。...冬コミC97にサークル参加してみた去る2019/12/31、コミケに初参加してきました。...技術書典7でESP32とmruby関連の新刊出します技術書典7もいよいよ明日になりました。さんコメントに気づくのが大変遅くなってすみません。Transcoderは自身でコンパイルする必要があります。さんお忙しい中失礼します。