I wonder if it would been better if we had gone another route with the
whole #require_relative thing. Instead of a special require method, we
could have a method that adds the current file’s directory to the top of
the $LOAD_PATH temporarily while a block executes.
For example, lets say we have a library `fruit_basket’ with:
On Jun 12, 2012, at 9:34 PM 6/12/12, Intransition wrote:
Then in fruit_basket.rb:
Hey Intransition.
you might have better luck emailing ruby-core if you’re interested in
this an can’t work it out.
Have you looked through the ruby-lang archives? The first hit I found
for require_relative was this: http://www.ruby-forum.com/topic/148978
which seems to indicate there wasn’t much discussion about the
functionality. What’s cool is that it also shows that require_relative
was originally ruby code, not C.
Assuming that it was rewritten in C (I haven’t checked), I imagine it
was to ensure performance. 1.9 had a lot of performance improvements
over 1.8.
What for? This is needlessly munging a global variable. Also, if one
of the required scripts also happen to require something, it will
become a relative require, too. (Unless you add some magical guard
code for this, and then we’re on a slippery slope.)
On Wednesday, June 13, 2012 10:40:08 AM UTC-4, Bartosz Dziewoński wrote:
What for? This is needlessly munging a global variable. Also, if one
of the required scripts also happen to require something, it will
become a relative require, too. (Unless you add some magical guard
code for this, and then we’re on a slippery slope.)
Ah good point. It wouldn’t become relative exactly, but it could
(however
unlikely) conflict name wise. However, since one is requiring relative
to a
current file it is more likely that one would be aware of any such
issue.
Say a local ostruct.rb file when one actuall wants the ruby one.
To clarify my implementation concept was something along the lines of:
def relative(&block)
dir = File.dirname(eval('__FILE__', block.binding))
$LOAD_PATH.unshift(dir)
block.call
$LOAD_PATH.delete(dir)
end
Obviously that would need to be improved upon, but that conveys the idea
of
it.
Anyway, you are probably correct. It just struck me b/c a pure Ruby
implementation of #require_relative is not very robust as it has to use caller, so I think its interesting that this block form never cropped
up
before. If it had, I wonder if #require_relative ever would have come
about
–there was such resistance to it by matz for so long.
Say we have grafted fruits in fruit_basket such as
lib/fruit_basket/lemon-orange.rb:
lemon seedling with orange grafted on
require ‘lemon’
require ‘orange’
Note that this file depends on being loaded from inside
fruit_basket.rb’s relative block, but that is not explicitly stated:
lib/fruit_basket.rb:
relative do
require ‘lemon-orange’
# …
end
gem ‘color’
gem ‘flavor’
require ‘fruit_basket’
Which files were loaded?
require_relative doesn’t have the problem of the reader of the source
needing external information to determine “which directory does this
require operate in?” since it is explicit. I don’t see how you make it
explicit for require inside a relative block.
Say you have two threads:
gem ‘color’
gem ‘flavor’
Thread.start do
require ‘orange’
end
Thread.start do
require ‘fruit_basket’
end
Are one or two “orange.rb” files loaded? Which ones?
On Wednesday, June 13, 2012 9:20:34 AM UTC-4, Jams wrote:
Assuming that it was rewritten in C (I haven’t checked), I imagine it was
to ensure performance. 1.9 had a lot of performance improvements over 1.8.
Unfortunately I learned a few months ago that #require_relative has not
been optimized, so it is hardly any better for being written in C.
However,
I am hopeful that one day someone will take the time to optimize it as
it
is ripe for such treatment and then it could readily help boost load
speeds.
This forum is not affiliated to the Ruby language, Ruby on Rails framework, nor any Ruby applications discussed here.