Project

General

Profile

Actions

Feature #18401

closed

Rework `require_relative` to add the "current path" on `$LOAD_PATH`

Feature #18401: Rework `require_relative` to add the "current path" on `$LOAD_PATH`

Added by vo.x (Vit Ondruch) almost 5 years ago. Updated about 1 month ago.

Status:
Feedback
Assignee:
-
Target version:
-
[ruby-core:106606]

Description

I think that since inception of require_relative, the implementation is wrong and is going against the spirit of require functionality. Let me explain.

If there is require "foo", it does something like:

r = $LOAD_PATH.select {|lp| File.exist? File.join(lp, "foo")}.first
load(r)

But require_relative "foo" does something different:

r = File.join(File.realpath(__dir__), "foo")
load(r)

Please note that this is problematic if mixture of require and require_relative (not mentioning __FILE__ and __dir__ are used. The major difference is actually the File.realpath here, because it expands symlinks and that is difference to require and may allow double loading.

My proposal is to change the require_relative in following way:

$LOAD_PATH.unshift __dir__
require "foo"

In essence, non of the require_relative, require, __FILE__ or __dir__ would need to use real path. The scenario bellow would provide expected output:

$ mkdir a
$ mkdir b
$ echo 'puts __dir__' > a/test.rb
$ cd b
$ ln -s ../a/test.rb test.rb
$ ruby test.rb
/home/vondruch/ruby/a

This would also resolve issues such as #16978, #10222 or #17885

Updated by nobu (Nobuyoshi Nakada) about 1 month ago Actions #1 [ruby-core:126819]

  • Status changed from Open to Feedback

vo.x (Vit Ondruch) wrote:

My proposal is to change the require_relative in following way:

$LOAD_PATH.unshift __dir__
require "foo"

Do you mean require_relative should load the file in the current working directory?
I don't think it is reasonable behavior.
require_relative binds the caller's location more tightly, and should not be affected by the runtime environment.

In essence, non of the require_relative, require, __FILE__ or __dir__ would need to use real path. The scenario bellow would provide expected output:

$ mkdir a
$ mkdir b
$ echo 'puts __dir__' > a/test.rb
$ cd b
$ ln -s ../a/test.rb test.rb
$ ruby test.rb
/home/vondruch/ruby/a

Isn't this the same as the current behavior?

Actions

Also available in: PDF Atom