From: "trans (Thomas Sawyer)" Date: 2013-08-17T20:51:06+09:00 Subject: [ruby-core:56684] [ruby-trunk - Feature #8781] Use require_relative() instead of require() if possible Issue #8781 has been updated by trans (Thomas Sawyer). But it doesn't matter *if* it is downward, b/c it is relative to the internal structure. If I move something around in my internal structure, that I might have alter a require statement is to be expected. In your example, if we move `foo/bar/baz` we'll still break a require, regardless of where foo.rb resides. Worse still, if an external program had depended on the location of foo.rb, moving foo.rb would break their program. In practice, the foo.rb of your example rarely moves, by its very design. It represents a component and the things under `foo/` are its subcomponents. Some code in the file might move but not the file itself. I feel like you are making something of a strawman argument against using require_relative b/c it is doing exactly what require_relative is supposed to do. Meanwhile ignoring its benefits. I really don't understand the objection to it. Used judiciously (better than "properly"?) it works quite well. As for "proper" use, two dollars to a donut most of those uses of `../` relative requires will be in test scripts. I don't even have to look. That's okay b/c it's localized to building the project. I'd still recommend removing it, for example adding `test` directory to the $LOAD_PATH when running tests. The usage I am talking about is within lib where we are structuring our programs from top level structures to low level structures. It's just the common pattern that we've all used: module MyApp -> myapp/ class Foo -> foo.rb and foo/ class Bar -> foo/bar.rb So in foo.rb we require 'foo/bar.rb' not the other way around. That's all I mean by "proper". Hey, let me make one other interesting point. I would be totally supportive of not using require_relative --requiring relative to the current file, if we could require relative to the current library's base directory. The load system I created actually has this feature. I think it is really the most "proper" solution of all, but it requires that Ruby have some notion of a library as having a base directory. (To clarify, in your example code `lib/foo/` is the base directory of the library.) ---------------------------------------- Feature #8781: Use require_relative() instead of require() if possible https://bugs.ruby-lang.org/issues/8781#change-41216 Author: ko1 (Koichi Sasada) Status: Open Priority: Normal Assignee: Category: lib Target version: current: 2.1.0 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? -- http://bugs.ruby-lang.org/