プログラミング言語 Crystal

Crystal の日本語ドキュメントはしばらく更新されておらず情報が古くなっているため、できるだけ原文の英語ドキュメントで最新の情報を参照ください。

翻訳にご協力いただける方は翻訳プロジェクトの issue や Crystal-JP の Slack からお知らせください。

ファイルの require

小さなプログラムやベンチマーク用途のコードであれば1つのファイルに書いても OK ですが、大きなプログラムの場合は、複数のファイルに分けることでメンテナンスが楽になり、また理解もしやすくなります。

コンパイラに別のファイルを処理させたいときは require "..." を使用します。引数には1つの文字列リテラルをとり、その書き方によって様々な形式で対象を指定することができます。

ファイルが require されると、コンパイラはその絶対パスを記憶し、以降ではそのファイルに対する require は無視されます。

require "ファイル名"

このように記述した場合、require パスの中で「ファイル名」のファイルを探します。

デフォルトの require パスは、コンパイラとあわせて提供される標準ライブラリと、カレントディレクトリ (UNIX シェルで言う pwd) から相対的に指定される「libs」ディレクトリ となっています。探索の対象となるディレクトリはこれらのみです。

ファイルの探索は以下の流れで処理されます。

  • もし「ファイル名.cr」というファイルが require パスに見つかれば、そのファイルをロードする
  • もし「ファイル名」のディレクトリが見つかり、そこに「ファイル名.cr」というファイルが含まれていれば、そのファイルをロードする
  • それ以外の場合はコンパイルエラーとなる

特に2番目のルールは、プロジェクトの典型的なデイレクトリ構造にマッチしているためとても便利です。

- project
  - libs
    - foo
      foo.cr
    - bar
      bar.cr
  - src
    - project.cr
  - spec
    - project_spec.cr

require "./filename"

このように記述した場合、require を実行したファイルから相対的に「ファイル名」のファイルを探します。

ファイルの探索は以下の流れで処理されます。

  • もし「ファイル名.cr」というファイルが現在のファイルからの相対パスに見つかれば、そのファイルをロードする
  • もし「ファイル名」のディレクトリが見つかり、そこに「ファイル名.cr」というファイルが含まれていれば、そのファイルをロードする
  • それ以外の場合はコンパイルエラーとなる

この相対パス参照はプロジェクトの中で他のファイルを参照するときによく使われます。また、spec からコードを参照する場合にも利用されます。

# spec/project_spec.cr
require "../src/project"

その他の形式

上記したどちらのケースでも、ネストされた形式で名前を指定することが可能で、その場合にはネストされたデイレクトリを探索します。

  • require "foo/bar/baz" は require パスの「foo/bar/baz.cr」または「foo/bar/baz/baz.cr」を探す
  • require "./foo/bar/baz" は現在のファイルから相対的に「foo/bar/baz.cr」または「foo/bar/baz/baz.cr」を探す

また、「../」を使えば、現在のファイルの親ディレクトリを指定することができます。require "../../foo/bar" のように書くことも同様に可能です。

これらのすべてのケースにおいて、 *** という特別なサフィックスを利用することができます。

  • require "foo/*" は「foo」デイレクトリにあるすべての「.cr」ファイルを require し、「foo」内のディレクトリの中は参照しない
  • require "foo/**" は「foo」デイレクトリにあるすべての「.cr」ファイルを require し、さらに「foo」以下のディレクトリを再帰的に参照する