From: shevegen@... Date: 2017-08-24T07:40:49+00:00 Subject: [ruby-core:82459] [Ruby trunk Feature#8781] Use require_relative() instead of require() if possible Issue #8781 has been updated by shevegen (Robert A. Heiler). Martin D��rst 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: