"require_next"?


(Joel VanderWerf) #1

Trying to run irb on QNX6, I learned that there is a 48 char limit to
file names. The long filenames generated by Tempfile (called from
irb/locale.rb) were preventing irb from running. So I installed the
following code in site_ruby under the name “tempfile.rb” so that it
would be loaded before the real tempfile:

==== tempfile.rb ====
basename = File.basename(FILE)
$".delete(basename)
dirname = File.dirname(FILE)
idx = $:.index(dirname)
$:.delete(dirname)
require basename
$:.insert(idx, dirname)

class Tempfile
alias long_filename_initialize initialize
def initialize(basename, tmpdir=Dir::tmpdir)
basename = basename[/.{0,25}$/] # last 25 chars
long_filename_initialize(basename, tmpdir)
end
end

···

=====================

It’s a horrible hack. What I would really like is something like "super"
but which applies to the way require finds files, rather than the way
ruby finds methods. (One problem with this hack is that whatever happens
during “require basename” had better not depend on the directory that
was temporarily hidden, or else you may get the wrong file or no file at
all.)

Is there an easy way to implement this in ruby? If not, should it be
provided as a primitive by the interpreter?


(Carlos) #2

Trying to run irb on QNX6, I learned that there is a 48 char limit to
file names. The long filenames generated by Tempfile (called from
irb/locale.rb) were preventing irb from running. So I installed the
following code in site_ruby under the name “tempfile.rb” so that it
would be loaded before the real tempfile:
[…]
Is there an easy way to implement this in ruby? If not, should it be
provided as a primitive by the interpreter?

How about something like that?:

def require_next the_first
basename = File.basename(the_first)
dirname = File.dirname(the_first)
loaded = false
idx = $:.index(dirname)+1
$:[idx…-1].each do |dir|
begin
require "#{dirname}/#{basename}"
loaded = true
break
rescue LoadError
next
end
end
raise LoadError, basename if !loaded
end

require_next FILE

(not tested).


(Carlos) #3

[…]

def require_next the_first
[…]
$:[idx…-1].each do |dir|
begin
require “#{dirname}/#{basename}”
^^^^^^^ only “dir” here, no “dirname”