はじめに

モジュールを使って、名前空間を適切に分けられるようになりましたか?
前回は、モジュールとミックスインについてお伝えしました。
モジュールを使うと、手軽にメソッドをグループ化することができます。
とはいえ、大きなプログラムを書くときには、ひとつのファイルが非常に長くなってしまいます。
このため、ある程度大きいプログラムを書くときには、複数のファイルに分割する必要があります。
この記事では、Ruby初心者の方向けに、プログラムを複数のファイルに分割する方法についてお伝えしていきます。
これはライブラリを読み込むときにも必要となりますので、しっかり覚えておきましょう。

requireでライブラリを読み込んでみよう

Rubyでは標準で多数のライブラリが提供されており、なにもしなくても使えるようになっています。
しかし、明示的に読み込まなければ使えないモジュールもあります。
その場合は、次のように「require関数」を使ってモジュールを読み込んでから使います。
例:

require 'uri'
puts URI.decode("https://search.yahoo.co.jp/search?p=%E3%83%AB%E3%83%93%E3%83%BC")

ここでは、例として標準ライブラリの”URIモジュール”を読み込んでいます。
正しくURLがデコードされているのが確認できますね。
1行目のrequireがなければ、モジュールが見つからずにエラーとなります。
requireの特徴として、同じファイル(モジュール)は一度しか読み込まないことが挙げられます。
つまり、同じファイルを何度requireしても最初の一度だけしか実行されないということです。
これには、無用な読み込みを防止する効果があります。
それでは、今度は自分でプログラムをモジュール分割して、それを読み込んでみましょう。

プログラムを複数のファイルに分割しよう

まずは、プログラムを複数のファイルに分割する必要があります。
次のように、新しいファイル(hello.rb)を作って、コードを書きましょう。

hello.rb:
module Hello
    def self.say
        puts "Hello, Module!"
    end
end

ここでは、”Helloモジュール”の中に”sayメソッド”を定義しています。次に、このモジュールを読み込んで使ってみましょう。それには、別のファイル(main.rb)に次のように記述します。

main.rb:
require './hello'
Hello.say

1行目のrequireに注目して下さい。
先ほどのファイル名が指定されています。
require関数は拡張子を補完してくれるため、”.rb”をつける必要はありません。
ファイル名だけではカレントディレクトリが検索されないため、明示的に”./”をつけてカレントディレクトリであることを示す必要があります。
後は、通常のモジュールとしてアクセスできます。

プログラムを再読み込みしたいときはloadを使う

他のプログラムを読み込む方法は、”require関数”だけではありません。
もうひとつの方法として、「load関数」があります。
”require関数”との違いは、実行する度に何度でも読み込まれることです。
試しに、次のようなファイルを用意して、実験してみましょう。

hello.rb:
puts "Hello, load!"
main.rb:
puts "一回目のload"
load 'hello.rb'
puts "二回目のload"
load 'hello.rb'

この例を実行すると、複数回読み込まれているのが確認できますね。
注意しておきたいのは、”require関数”とはファイル名の指定方法が違うことです。
”load関数”では、拡張子を記述する必要があります。
逆に、カレントディレクトリであることを明示する必要はありません。
強制的に再読み込みさせたいときなどは、”load関数”を使うとよいでしょう。

autoloadを使って、読み込みを遅らせる

最後に、「autoload関数」による読み込み方法を説明していきます。
”autoload関数”の特徴は、必要になるまでファイルの読み込みを行わないことです。
これにより、大量のファイルが指定されていても、最初に負荷が集中することを避けられます。
使い方は、次のとおりです。

hello.rb:
module Hello
    def self.say
        puts "Hello"
    end
end
puts "autoloaded"
main.rb:
autoload :Hello, './hello'
puts "この時点では読み込まれていません"
Hello.say

例を実行すると、最初にモジュールにアクセスした時点で読み込まれていることが確認できますね。
”autoload関数”の引数には、シンボルとファイル名が必要です。
シンボルは定数文字列のようなもので、先頭に「:(コロン)」をつけることでシンボルになります。

まとめ

プログラムを複数のファイルに分割する方法がお分かりになりましたか?
他のファイルに分割したプログラムを読み込む方法は3つあります。
状況に応じて、適切な方法を使いましょう。
また、ライブラリを使うときにもファイルの読み込みが必要になります。読み込みを忘れないようにしましょう。