https://bugs.ruby-lang.org/https://bugs.ruby-lang.org/favicon.ico?17113305112018-07-20T19:17:47ZRuby Issue Tracking SystemRuby master - Feature #14927: Loading multiple files at oncehttps://bugs.ruby-lang.org/issues/14927?journal_id=730482018-07-20T19:17:47Zshevegen (Robert A. Heiler)shevegen@gmail.com
<ul></ul><p>I wanted to propose a more sophisticated load-process in ruby some time ago, but I never got<br>
around it. I am even thinking of being able to load files based on abbreviations/shortcuts,<br>
without necessiting a hardcoded path (e. g. require needs the path, whereas with an<br>
abbreviation we could only refer to that abbreviation, and an internal list keeps track of<br>
where the actual file resides instead). But it's not so simple to suggest something that<br>
has a real chance of inclusion. I am glad to see other people have somewhat similar ideas -<br>
of course your suggestion is quite different from my idea, but you tap into a very similar<br>
situation:</p>
<ul>
<li>Handling multiple files.</li>
</ul>
<p>This is especially useful for larger ruby projects. For smaller projects it is not so important<br>
perhaps but when you have like +50 .rb files and growing, making things easier in regards to<br>
handling files, would be great.</p>
<p>To the suggestion - I think several ruby hackers may benefit from better handling of files.</p>
<p>I am not sure if there is a big chance to see load() and require() itself being changed, but<br>
I also don't know. I think we should ask matz, but there may be a chance that they may not be<br>
changed, possibly due to backwards compatibility (if there is a problem). In the long run we<br>
may want to consider using alternative means. For example, the require-family, such as<br>
require_relative(). I don't mean require_relative in itself, but something related to require_*.</p>
<p>require_relative also handles location to other files, just relative to the directory at hand.</p>
<p>By the way, I also understand this use case:</p>
<blockquote>
<p>This approach may not work if your files have dependencies like that:</p>
</blockquote>
<p>And it is related to another use case which isn't a lot of fun:</p>
<ul>
<li>Circular dependencies + warnings about this</li>
</ul>
<p>I also thought about this with my never-written proposal... :D</p>
<p>Circular dependency warnings are not a lot of fun IMO.</p>
<p>I think Hiroshi Shibata also had a suggestion in regards to ... require, I think, some months<br>
or a few years ago, but I don't remember what it was exactly.</p>
<p>Anyway, before I write way too much and digress from the suggestion,<br>
I am in general in favour of your suggestion. I don't have any particular<br>
opinion on your proposed solution - another API may be fine or perhaps<br>
a new method... load_files() ? Hmm... may not be an ideal name either.<br>
But I think the specific API may be a detail. The more important aspect<br>
is whether ruby can provide easier means for ruby users to load or<br>
require a batch of files. Perhaps load() and require() will remain as<br>
they are, for simplicity and backwards compatibility, but in such a<br>
case we could think about better ways to handle the task of "pulling<br>
all necessary files" into a project. This may also help people when<br>
they create gems.</p>
<p>In my own larger gems I do something very similar as to what Sébastien<br>
Durand showed, e. g. I also do Dir['*.rb'] often on a per-directory<br>
basis. That way I don't have to specify the names of the individual<br>
.rb files.</p>
<p>Anyway, +1 from me.</p> Ruby master - Feature #14927: Loading multiple files at oncehttps://bugs.ruby-lang.org/issues/14927?journal_id=730502018-07-20T20:23:39Zahorek (Pavel Rosický)
<ul></ul><p>Dir glob has to find all files, sort them, create objects.<br>
Then require loads them again from the filesystem...</p>
<p>I think Dir.glob + require is a very common pattern and if we have a function like require_directory / require_tree? some of these unnecessary steps could be skipped and simplified.</p> Ruby master - Feature #14927: Loading multiple files at oncehttps://bugs.ruby-lang.org/issues/14927?journal_id=739382018-09-08T14:35:04Zshevegen (Robert A. Heiler)shevegen@gmail.com
<ul></ul><p>I thought about creating a new issue but then I remembered that<br>
the issue here refers to a similar use case that I wanted to<br>
show.</p>
<p>Take the following link as an example:</p>
<p><a href="https://github.com/jordansissel/fpm/blob/master/lib/fpm.rb" class="external">https://github.com/jordansissel/fpm/blob/master/lib/fpm.rb</a></p>
<p>In the event that the project may be relocated, here is the<br>
copy/paste outcome of that code:</p>
<pre><code>require "fpm/namespace"
require "fpm/package"
require "fpm/package/dir"
require "fpm/package/gem"
require "fpm/package/deb"
require "fpm/package/npm"
require "fpm/package/rpm"
require "fpm/package/tar"
require "fpm/package/cpan"
require "fpm/package/pear"
require "fpm/package/empty"
require "fpm/package/puppet"
require "fpm/package/python"
require "fpm/package/osxpkg"
require "fpm/package/solaris"
require "fpm/package/p5p"
require "fpm/package/pkgin"
require "fpm/package/freebsd"
require "fpm/package/apk"
</code></pre>
<p>As you can see, there are several require statements for the<br>
subdirectory at fpm/package/.</p>
<p>I think this is a very common use case. I encounter it myself<br>
a lot in (almost) daily writing of ruby code, where I have to<br>
load code stored in .rb files spread out.</p>
<p>Of course there are workarounds over the above, e. g. the<br>
Dir[] or Dir.glob example that was given here (and the former<br>
I use a lot). But I think it may be nicer to have an official<br>
API support this as well.</p>
<p>The name could be:</p>
<pre><code>require_files
</code></pre>
<p>The first argument could be the path to the subdirectory at<br>
hand; the second argument could be an options Hash that allows<br>
more fine-tuning, such as traversing subdirectories, handling<br>
.so files as well, or exclusively, and so on and so forth.</p>
<p>I believe it may fit into the "require" family, since that<br>
already has e. g. require_relative.</p>
<p>In the long run it would be nice to even be able to refer to<br>
.rb files without having to use any hardcoded path at all -<br>
but for the time being, any support for requiring/loading<br>
files helps a lot.</p>
<p>(To the issue of dependencies in said .rb files, I usually<br>
batch-load the .rb files, and if I get some error about<br>
an uninitialized constant, I add it into that .rb file at<br>
hand. It's a bit cumbersome but I understand that this part<br>
is not easy to change presently.)</p>
<p>I think require_directory() is a better name that require_tree()<br>
but I also like require_files().</p>
<p>The more important part is to want to convince that this is<br>
a common pattern, which is also why I added an example from<br>
a quite popular ruby project (fpm presently has ~7.3 million<br>
downloads on rubygems.org).</p>
<p>What I encounter myself doing is that, for my larger projects<br>
in ruby, I end up creating a subdirectory called requires/ and<br>
in that directory I put .rb files that handle loading of<br>
require-related activities, including subdirectories and external<br>
dependencies.</p> Ruby master - Feature #14927: Loading multiple files at oncehttps://bugs.ruby-lang.org/issues/14927?journal_id=739502018-09-09T04:33:32Znobu (Nobuyoshi Nakada)nobu@ruby-lang.org
<ul></ul><p>shevegen (Robert A. Heiler) wrote:</p>
<blockquote>
<p>In the event that the project may be relocated, here is the<br>
copy/paste outcome of that code:</p>
<pre><code>require "fpm/namespace"
require "fpm/package"
require "fpm/package/dir"
require "fpm/package/gem"
require "fpm/package/deb"
require "fpm/package/npm"
require "fpm/package/rpm"
require "fpm/package/tar"
require "fpm/package/cpan"
require "fpm/package/pear"
require "fpm/package/empty"
require "fpm/package/puppet"
require "fpm/package/python"
require "fpm/package/osxpkg"
require "fpm/package/solaris"
require "fpm/package/p5p"
require "fpm/package/pkgin"
require "fpm/package/freebsd"
require "fpm/package/apk"
</code></pre>
</blockquote>
<p>Doesn't the order matter?</p> Ruby master - Feature #14927: Loading multiple files at oncehttps://bugs.ruby-lang.org/issues/14927?journal_id=739512018-09-09T05:28:35Zmarcandre (Marc-Andre Lafortune)marcandre-ruby-core@marc-andre.ca
<ul></ul><p>nobu (Nobuyoshi Nakada) wrote:</p>
<blockquote>
<p>Doesn't the order matter?</p>
</blockquote>
<p>Very often, it does not. If it does, one can always require the one that's needed first, say, then require the whole directory; require won't load the same file twice so this works fine.</p>
<p>We wrote a small method for this in <code>deep-cover</code>: <a href="https://github.com/deep-cover/deep-cover/blob/master/core_gem/lib/deep_cover/tools/require_relative_dir.rb" class="external">https://github.com/deep-cover/deep-cover/blob/master/core_gem/lib/deep_cover/tools/require_relative_dir.rb</a></p>
<p>One thing I really like about it is that it makes it clear that the whole directory is loaded. If there's a missing <code>require "fpm/package/something"</code> in the list above, it can take a while to notice.</p>
<p>My opinion on the feature request: not great for <code>load</code>, but could be useful for multiple <code>require_relative</code>.</p> Ruby master - Feature #14927: Loading multiple files at oncehttps://bugs.ruby-lang.org/issues/14927?journal_id=740762018-09-18T00:38:28Zmarcandre (Marc-Andre Lafortune)marcandre-ruby-core@marc-andre.ca
<ul><li><strong>Assignee</strong> set to <i>matz (Yukihiro Matsumoto)</i></li></ul><p>Until we convince Matz, I pushed a gem <code>require_relative_dir</code> which hopefully can be helpful to others.</p>