Rubyでコンストラクタと言えば、インスタンスを生成した際に1度だけ実行されるinitializeメソッドのことです。なお、オブジェクト指向のプログラム言語のRubyは、扱うデータの全てがオブジェクトです。そして、同じクラスから複数のインスタンスを作ることがよくあります。
そのような場合、initializeメソッドによりインスタンス内で使える固有の定数を設定しなければなりません。Rubyでインスタンスを使うなら、ぜひコンストラクタの使い方をマスターしましょう。今回はRubyのコンストラクタの機能について紹介します。
コンストラクタとは
Rubyのようなオブジェクト指向言語では、その概念に由来する独特の用語を使います。そしてオブジェクト指向では、独特のカタカナの専用用語が使われていますが、そして今回紹介するコンストラクタもその1つです。ぜひ、そのような専門用語の意味の理解を理解して、Rubyを使いこなせるようになりましょう。
まずはコンストラクタの基本について解説します。
コンストラクタとは何か
コンストラクタとは、Rubyのようなオブジェクト指向のプログラミング言語で使われる機能の1つで、オブジェクトを生成した際に1度だけ実行される機能を指す名称です。なお、オブジェクトが生成された際にのみ実行されることから、そのオブジェクト内で共通に使えるインスタンス変数の初期化などに使われます。
ただしクラスを定義した際、コンストラクタを必ず作る必要はありません。コンストラクタが定義されていなくてもオブジェクトを生成できます。また、Rubyではオブジェクトを生成するnewメソッドの引数を利用して、コンストラクタによる変数の初期化も可能です。
コンストラクタの元々の意味は
コンストラクタは、英語のconstructorが基になったIT用語です。では、英語のconstructorにはどのような意味があるのでしょうか。
英語のconstructorは、建設者、建設会社という意味です。日本で大きなビルを建設する大手業者をよくゼネコンと言いますが、これはGeneral Contractorの略で、日本語では総合建設業を訳されます。つまり今回紹介しているRubyのコンストラクタは、英語のconstructorと関係がありません。
しかしconstructorの動詞形のcontractには契約するという意味があります。そのため、オブジェクトを生成した際の契約手続きとして実行する機能がコンストラクタ(constructor)だと理解すると良いでしょう。
コンストラクタが実行されるタイミング
先ほど紹介したように、コンストラクタはnewメソッドによってインスタンスが作られると同時に実行されます。なおインスタンスとは、ちょうど設計図にあたるクラスを基に作られた実体に相当するIT用語です。そして設計図であるクラスの状態では、コンストラクタとして実行されません。
newメソッドにより設計図のクラスから実際に動作するインスタンスが作られると、コンストラクタが実行されます。なおコンストラクタはinitializeメソッドとして記述されており、それが実行できるのはインスタンスが生成された1度だけです。後からinitializeメソッドを呼び出すことはできません。
Rubyのコンストラクタの書き方
先ほど紹介したようにRubyのコンストラクタとして実行されるのが、クラスの中に記述されたinitializeメソッドです。次から、このinitializeメソッドの書き方について解説します。
initializeメソッドの書き方
initializeメソッドは、ユーザー定義のメソッドと同じようにクラスの中に定義します。ただし、コンストラクタとして利用できるメソッド名はinitializeのみです。下記のように「def initialize()」を利用して記述してください。
initializeメソッドの書き方の例
class Sample def initialize() p "初期化処理" end end sample = Sample.new
initializeメソッドに引数を指定する
Rubyのコンストラクタは、newメソッドでオブジェクトを生成する際に引数を渡すことが可能です。そして、newメソッドで指定した引数を利用するためには、initializeメソッドにも引数を指定します。
引数を用いたinitializeメソッドの書き方の例
class Sample def initialize(str) p str end end sample = Sample.new("引数ありの初期化処理")
この例では、Smapleクラスを生成した際にnewメソッドに引数を指定し、その引数をinitializeメソッドで活用しています。
initializeメソッド利用時の注意
もしinitializeメソッドを複数記述した場合、最後に記述されたinitializeメソッドが適用されます。とはいえ誤動作の原因になるのでinitializeメソッドはクラスに1つだけ記述してください。
またinitializeメソッドは、インスタンスの外部から呼び出したりできません。さらに一般的なメソッドのように値を返すこともできません。initializeメソッドにretuenを書いた場合、エラーにはなりませんが、その値を戻せないので注意してください。
コンストラクタの役割
コンストラクタの役割とは、インスタンス内の共通で使用する変数の設定や、インスタンスが生成された際に実行されるアクションの実行です。次から例を用いてコンストラクタの役割を紹介します。
インスタンス変数を初期化する
Rubyのインスタンス内で共通に使える変数がインスタンス変数です。そして、もしインスタンス内のメソッドがインスタンス変数を使用しているなら、そのメソッドを利用する前、具体的にはインスタンスが生成されたタイミングで設定されなければなりません。
そこでRubyのコンストラクタでは、インスタンス変数の初期化に使われます。なお、Rubyではインスタンスを生成するnewメソッドで引数を指定することで、その値をインスタンス変数に設定することが可能です。
下記の例は、newメソッドでインスタンスを作成する際、引数に”myname”を指定しています。そのnewメソッドで生成されるインスタンスでは、コンストラクタのdef initializeでその引数をnameで受け取り、インスタンス変数の@nameに代入しています。
インスタンス変数を初期化する例
class Foo def initialize(name) @name = name end def view_name() p @name end end obj = Foo.new("myname") obj.view_name()
アクションの実行する
先ほどインスタンス変数の初期化例を紹介しましたが、コンストラクタはインスタンス内のメソッドで利用するための準備のためのアクションにも使われます。
例えばインスタンスで処理するためのファイルを用意したり、制御するためのプロセスを生成しておく、といったアクションが可能です。
次にインスタンス内のメソッドで利用するファイルを準備するコンストラクタを含む例を紹介します。
class Logmaker def initialize(logfile) @logfile = logfile File.open(@logfile, mode="w") do |f| f.write("Log file start!\n") end end def log_write(message) File.open(@logfile, mode="a") do |f| f.write(message) end end end obj = Logmaker.new("log.txt") obj.log_write("1st message\n")
まとめ
これまで紹介したように、コンストラクタとはインスタンスを生成した際に1度だけ実行されるinitializeメソッドのことです。そしてインスタンス内の共通で使えるインスタンス変数の設定などで使われます。さらにinitializeメソッドは、newメソッドで指定する引数を使うことも可能です。
Rubyでインスタンスを作成する際は、今回紹介したコンストラクタをうまく活用してシステム開発に役立ててください。