Why relative path doesn't work in Ruby require

Amaynut picture Amaynut · Aug 14, 2014 · Viewed 24.8k times · Source

I'm starting learning Ruby, one thing that I don't understand, why relative path for require directive doesn't work in ruby. It's something that works almost in every scripting language that I now (JSP, PHP...). I explain with a real example. I have a folder named shapes which contains 3 classes shape, rectangle and square. I have also another file test_shapes.rb from where I call and test my classes. When I import my classes to the main file like this:

require "./shape"
require "./rectangle"
require "./square"

I got error for files not found. When I include the name of my subfolder like this:

require "./shapes/shape"
require "./shapes/rectangle"
require "./shapes/square"

The code is perfectly working. Because I specified the whole path to the root directory of the project (the lib folder I think). When I include I include the absolute path to the hard disk, like this:

require "#{File.dirname(__FILE__)}/shape"
require "#{File.dirname(__FILE__)}/rectangle"
require "#{File.dirname(__FILE__)}/square"

It's also working perfectly.

So, I just want some explanation if know why the first import method (the relative path to the current folder) in not working.

Answer

nacyot picture nacyot · Aug 14, 2014

Relative path is based on working dir. I assume that there is main file on the same directory. If you run ruby ./shapes/main.rb on project root, ruby try to find {project_root}/shape.rb, not {project_root}/shapes/shape.rb. It doesn't work.

You need to use require_relative like below.

# {project_root}/shapes/main.rb
require_relative './shape'
require_relative './rectangle'
require_relative './square'