Rubyはインタプリタ型のプログラム言語であり、変数を柔軟に使えてプログラムを手軽に実行できます。しかし、Rubyはコンパイル型として使えない、ということではありません。Rubyをコンパイルして使う方法もあります。
今回はRubyのインタプリタ型の仕組みと特徴を紹介します。
インタプリタとは?
プログラム言語は大きく分けるとインタプリタ型とコンパイル型に分けられます。Rubyはインタプリタ型のためプログラムコードを読み込み、そのプログラムコードを解析しながら実行します。
まずはRubyのインタプリタ型の仕組みをコンパイル型と比較しながら解説します。
CPUが実行する仕組み
Rubyなどのコンピュータプログラムとは、パソコンなどのCPUが動作する命令の組み合わせを、人が読めるようにしたものです。実際にCPUで実行するには、人が読めるプログラムをCPUが実行できる命令に変換します。
具体的にRubyは、人が読めるRubyのプログラムを読み込み、それをCPUで実行する命令に逐次変換することでプログラムに書かれた処理を実行します。
そしてCPUが実行できる命令に変換する仕組みには、インタプリタ型の仕組みをコンパイル型の2つがあり、Rubyのように逐次変換する仕組みがインタプリタ型です。一方、コンパイル型はプログラムコードを一括してCPUが実行できる命令の組み合わせに変換し、それをファイルに書き出して、実行ファイルを作成します。
インタプリタ型のメリットとデメリット
先ほどRubyのようなインタプリタ型はプログラムコードをパソコンなどのCPUの命令に逐次変換して実行すると紹介しましたが、この方法はプログラムの編集と実行を何度も繰り返す開発方法に向いています。
ただし逐次変換するのに時間がかかるため実行速度の遅く、インタプリタ型のデメリットとして挙げられます。さらにRubyでは変数の型を予想して自動的にクラスを割り当てたり、オブジェクトを生成するなど多くの処理をやっているので、インタプリタ型のプログラムでも処理速度が遅い言語です。
コンパイル型のメリットとRubyとの関係
先ほどインタプリタ型のメリットとデメリットを紹介しましたが、コンパイル型のメリットとデメリットはインタプリタ型の逆と言えます。
コンパイル型のメリットは実行速度の速さで、特にC言語やC++で作成したプログラムは直接CPUが実行する命令に変換されるので高速に動作します。ただし、プログラムを実行可能な命令の組み合わせへの変換に時間がかかるうえ、プログラムのコンパイルと実行を別々に実行しなければならない点がデメリットです。
インタプリタ型の特徴
Rubyは、rubyまたはruby.exeという実行モジュールがRubyのプログラムを読み込み、そのプログラムに書かれた内容を解析しながら実行するインタプリタ型のプログラム言語です。次からRubyを例にインタプリタ型の特徴を紹介します。
プログラムを解析しながら実行する
インタプリタ型の特徴は、読み込んだプログラムを逐次解析しながら実行できる点です。例えば、変数に値を代入する場合、自動的に値の型を判別し、それに合わせて変数の型を変更できます。さらにプログラムの途中で変数を使っても、自動的にその変数の領域を確保します。
そのためインタプリタ型には変数の型宣言が不要なプログラム言語が多く、Rubyもプログラムの途中で新しい変数が使えます。しかしコンパイル型はあらかじめ変数を宣言し、領域を確保したうえで変数を使います。
処理が遅い
インタプリタ型の最大の欠点とも言えるのが処理速度の遅さです。特にRubyは、読み込んだプログラムを解析し、処理に応じて自動的にオブジェクトの生成や変更を繰り返すので、その処理に時間がかかります。
それに対してC言語やJavaなどのコンパイル型の言語は、実行するCPUやバーチャルマシンの命令に合わせて作られているので、最適な命令の組み合わせに変換可能です。
そのため処理速度が求められるゲーム開発では、コンパイル型のC++よくが使われます。それに対しインタープリタ型はそれほど処理速度を求められないRuby on RailsのようなWebシステム開発に使われます。
変数の型宣言の違い
インタープリタ型とコンパイル型で、プログラミングスタイルに差がでやすいのが変数の型です。インタープリタ型は変数が処理された段階で自動的に調整できるため、同じ変数に数字も文字も代入できます。
しかしコンパイル型はそのような調整ができません。特にC言語ではメモリー上にあらかじめ数字または文字の領域を確保して処理することから、ハードウェアを意識したプログラミングが求められます。
ただしインタプリタ型だとしても変数の型を無視して使っても良い、という訳ではありません。Rubyでは数字と文字を別のクラスのオブジェクトとして扱い、使えるメソッドも違います。そのためインタープリタ型でも変数の型を意識したプログラミングが求められます。
Rubyのプログラムをコンパイル型として使う仕組み
これまで紹介したようにRubyはインタプリタ型のプログラム言語です。しかしRubyをコンパイル型として利用できない、ということではありません。組み込み用途のような限られた環境向けに、Rubyのプログラムをコンパイルして使用する仕組みがあります。
次からRubyのプログラムをコンパイル型として使う仕組みについて紹介します。
Rubyの処理を実行するVMを使う
Rubyのプログラムは、その独特な考え方からC言語やC++のようにCPUで直接動作できる命令には変換できません。とはいえ、全く方法が無い、ということではありません。Rubyのプログラム処理に最適なCPUを作れば、それを対象にRubyのコンパイラを作成することが可能です。
そこでバーチャルマシン(virtual machine)という技術を利用します。なおバーチャルマシンはコンピュータの動作を再現するためのソフトウェアで、CPUのアーキテクチャの違いを吸収する仕組みとして使われる技術です。
そのためRubyのプログラム実行に合わせたバーチャルマシンを作ることで、Rubyのプログラムをそのバーチャルマシン向けの命令にコンパイルする仕組みを作れます。
組み込み用途のmruby
組み込み用途向けに開発されたRubyのプログラムをコンパイルして利用する仕組みがmrubyです。組み込み用途ではリソース不足によりインタプリタ型のプログラム実行に向いていません。
その点mrubyは、Rubyのプログラムをmrubyバイトコードに変換し、Rubyのバーチャルマシンがそのバイトコードを実行することで、使えるメモリーが少ない組み込み用のCPUでもRubyを使えるようにする仕組みを実現しています。
そしてC言語のプログラムからmrubyによる処理を呼び出せるので、C言語のように直接実行できるプログラムの中に組み込みことも可能です。
JavaVMを使うJRuby
先ほど紹介したmrubyのようにバーチャルマシンを利用することで、Rubyのプログラムを直接実行できないCPUでRubyを活用する仕組みがJRubyです。JRubyでは、RubyのプログラムからJava用バーチャルマシンで動作するバイトコードを生成します。
Javaはオブジェクト指向のコンパイル型プログラミング言語で、いろいろな用途で使われています。そしてJavaの特徴は、Java用バーチャルマシンを利用することでハードウェアの差を吸収し、どの機器でも同じように動作するプログラムを作れる点です。
JRubyはそのようなJavaVMで動作するバイトコードを生成することで、Rubyが動作しないコンピュータでもJavVMがあれば、Rubyを実行できる仕組みです。そのため、JRubyによりAndroid端末で動作するプログラムをRubyで作ることもできます。
まとめ
これまで紹介したようにRubyはインタプリタ型のプログラミング言語であり、インタプリタ型はコンパイル型に比べてプログラムを手軽に実行でき、変数を柔軟的に使えるなどのメリットがあります。しかし処理速度が遅いなどのデメリットもあるので、メリットとデメリットを正しく理解したうえで利用しましょう。
なおインタプリタ型のRubyですが、バーチャルマシンを使えばコンパイル型のように使うことも可能です。組み込み用途などでRubyを利用する場合は、そのような仕組みを利用でしてください。