Issue #8781 has been updated by shevegen (Robert A. Heiler).


Martin Drst wrote back then:

> On the other hand, 'require' has a tighter coupling to the file
> name than 'reqire_relative'.

Both have a similar requirement - you need to pass in the name of
the file at question.

Both also require some information to the directory tree that you
are operating on; with require_relative being relative to the
.rb file that it is being used.

I am thinking about proposing a different way altogether; e. g.
a way where we could describe the individual .rb files in a 
centralized manner, and access them; and then let ruby figure
out the best way to call them. But ... I have not really been
able to come up with any variant that could be great. It's
actually quite difficult.

Perhaps I can share my use case here. I lately rewrote two of my
largest projects in ruby, in total about 300.rb files or so (that's
large for me!).

Since I also split up the logic, and some of the code was years
old, this was not so easy; I had to rename files, I had to change
their positions and of course, due to the hardcoded names and
file paths still, I had to change all of that one by one. I also
had to build-up in a way to avoid circular dependency warnings.

All in all, that was a lot of time that I spent largely doing
re-shuffling of files (and of course, splitting the logic up,
fixing other problems and code style etc...).

My idea here was to be able to use shortcut identifiers for
(certain) files; or perhaps even all files.

For example, say I have files called:

  project_base_dir.rb
  project_yaml_dir.rb

What these files do is specify the path to the base directory
and the path to the yaml directory (I tend to have a yaml/ 
directory for many of my larger projects).

I would usually require them like so, if the name of the project
is "foobar" and top-namespace is Foobar, usually module Foobar:

  require 'foobar/project_base_dir.rb' # I like to add the extension name

I was thinking of an alternative way instead, something such as:

  require_in_project :project_base_dir

The above could be kept track of in a .yml file, where such dependencies
and file structures could be used. For that base directory file, it is
not a big deal, but I often have to add in more base .rb files, and
end up with lots of require lines which have hardcoded path entries
there.

I'd wish there was a way to just use identifiers like that instead,
because then I can always keep track of them in a SINGLE file alone,
rather than having to make modifications in all .rb files.

Not sure I was able to explain what I may want ... it's actually a bit
difficult to describe since it is more complex ... sorry for off-topic,
I just wanted to add a bit to this, in particular since perhaps we
can have some more powerful and sophisticated way in ruby 3.x to
deal with larger projects - should we really be required to have
all hardcoded file paths, in every .rb file, like oldschool C when
it comes to a project that already has a full "namespace", such
as in the example given above by "module Foobar"? Surely ruby could
infer some information from a common structure, and I really mean
common basic structures that people often tend to use here ... name
of the gem == toplevel namespace constant, usually a module, due to
being able to use "include NamespaceHere" lateron.

----------------------------------------
Feature #8781: Use require_relative() instead of require() if possible
https://bugs.ruby-lang.org/issues/8781#change-66269

* Author: ko1 (Koichi Sasada)
* Status: Open
* Priority: Normal
* Assignee: 
* Target version: next minor
----------------------------------------
I wrote a attached small script rrc.rb, stand for "RequireRelativeChecker".

This small script points out that require() can be replaced with require_relative().

"Detecting replace-able require()" algorithm is easy (and not perfect):
(1) If loaded file is at sub (or same) directory of requiring file.
(2) If requiring file foo.rb is at $LOAD_PATH, then check only foo/*.
See attached script for details.

This is a part of output.

####
/home/ko1/tmp/trunk/lib/ruby/2.1.0/cgi.rb:294: WARNING: Use require_relative() to require /home/ko1/tmp/trunk/lib/ruby/2.1.0/cgi/core.rb.
/home/ko1/tmp/trunk/lib/ruby/2.1.0/cgi.rb:295: WARNING: Use require_relative() to require /home/ko1/tmp/trunk/lib/ruby/2.1.0/cgi/cookie.rb.
/home/ko1/tmp/trunk/lib/ruby/2.1.0/date.rb:4: WARNING: Use require_relative() to require /home/ko1/tmp/trunk/lib/ruby/2.1.0/date/format.rb.
/home/ko1/tmp/trunk/lib/ruby/2.1.0/net/http.rb:1541: WARNING: Use require_relative() to require /home/ko1/tmp/trunk/lib/ruby/2.1.0/net/http/exceptions.rb.
/home/ko1/tmp/trunk/lib/ruby/2.1.0/net/http.rb:1543: WARNING: Use require_relative() to require /home/ko1/tmp/trunk/lib/ruby/2.1.0/net/http/header.rb.
/home/ko1/tmp/trunk/lib/ruby/2.1.0/net/http.rb:1545: WARNING: Use require_relative() to require /home/ko1/tmp/trunk/lib/ruby/2.1.0/net/http/generic_request.rb.
###

(all of warnings are attached)

How about to replace require() with require_relative() if it is possible?

Advantage:
* require_relative() is faster than require() especially with many gems.
* Easy to detect which file is loaded.

Disadvantage (incompatibility)
* We can't replace loading file with $LOAD_PATH trick.
(But I believe nobody expect such behavior)

(I also recommend other gem authors to  use require_relative)

Any comments?


---Files--------------------------------
rrc.rb (841 Bytes)
log (145 KB)


-- 
https://bugs.ruby-lang.org/

Unsubscribe: <mailto:ruby-core-request / ruby-lang.org?subject=unsubscribe>
<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-core>