Writing a program in a single file is OK for little snippets and small benchmark code. Big programs are better maintained and understood when split across different files.
To make the compiler process other files you use require "..."
. It accepts a single argument, a string literal, and it can come in many flavors.
Once a file is required, the compiler remembers its absolute path and later require
s of that same file will be ignored.
This looks up "filename" in the require path.
By default the require path is the location of the standard library that comes with the compiler, and the "libs" directory relative to the current working directory (given by pwd
in a unix shell). These are the only places that are looked up.
The lookup goes like this:
The second rule is very convenient because of the typical directory structure of a project:
- project
- libs
- foo
foo.cr
- bar
bar.cr
- src
- project.cr
- spec
- project_spec.cr
This looks up "filename" relative to the file containing the require expression.
The lookup goes like this:
This relative is mostly used inside a project to refer to other files inside it. It is also used to refer to code from specs:
# in spec/project_spec.cr
require "../src/project"
In both cases you can use nested names and they will be looked up in nested directories:
require "foo/bar/baz"
will lookup "foo/bar/baz.cr" or "foo/bar/baz/baz.cr" in the require path.require "./foo/bar/baz"
will lookup "foo/bar/baz.cr" or "foo/bar/baz/baz.cr" relative to the current file.You can also use "../" to access parent directories relative to the current file, so require "../../foo/bar"
works as well.
In all of these cases you can use the special *
and **
suffixes:
require "foo/*"
will require all ".cr" files below the "foo" directory, but not below directories inside "foo".require "foo/**"
will require all ".cr" files below the "foo" directory, and below directories inside "foo", recursively.