ruby picture

RCR 223: require a directory

Submitted by mgarriss (Thu Feb 26 16:02:47 UTC 2004)

Abstract

require should check for 'my_lib/my_lib' if 'my_lib' is not a .rb and instead is a directory.

Problem

In an attempt to keep their code separate from other's code, library authors have been using a trick like this:

  1. my_lib.rb
require 'my_lib/my_lib'

  1. my_lib/my_lib.rb
  2. actual code goes here

This is silly but needed because of how require works. It makes the site_ruby directory very messy for example. Sometimes there is actual code in the 'my_lib' but authors will still create a my_lib directory for additional code.
This trick/hack is used 29 times in the ruby standard library:
cgi.rb
cgi/session.rb
date.rb
drb/drb.rb
irb.rb
optparse.rb
rdoc/dot/dot.rb
rdoc/generators/template/chm/chm.rb
rdoc/generators/template/html/html.rb
rdoc/generators/template/xml/xml.rb
rdoc/markup/sample/sample.rb
rdoc/markup/simple_markup.rb
rdoc/rdoc.rb
rexml/dtd/dtd.rb
rexml/rexml.rb
rinda/rinda.rb
shell.rb
soap/mapping/mapping.rb
soap/rpc/rpc.rb
soap/soap.rb
test/unit.rb
test/unit/collector.rb
uri.rb
webrick.rb
webrick/httpauth.rb
webrick/httpservlet.rb
wsdl/wsdl.rb
xsd/xmlparser/xmlparser.rb
yaml.rb

Proposal

Rewrite 'require' to attempt to load 'my_lib/my_lib' if it can't load 'my_lib'. Some examples:

require 'my_lib' # searches for 'my_lib.rb' and 'my_lib/my_lib.rb'

require 'my_path/my_lib' # searches for 'my_path/my_lib.rb' and 'my_path/my_lib/my_lib.rb'

Analysis

This can not be done by a library writer because the user of the lib would still have to use the old require to require the library with the redefined require.

This could possibly break some code that might depend on not finding a argument given to require. Although this would be rare it could be fatal.

This is why this is submitted as a RCR.

Implementation

If it was done in pure Ruby it might look like this (thanks to batsman and chris2 for this code):
alias old_require require
def require lib
  old_require lib
rescue LoadError
  old_require( lib + "/" + File.basename(lib) )
end
ruby picture
Comments Current voting

Isn't this very similar to rejected RCR 95?

https://rcrchive.net/rgarchive/rejected.html#rcr95

--David Black

I don't see it as the same, David. I think that this is a case where we have:

  foo/foo.rb
  foo.rb

If I require 'foo', then foo.rb will be loaded. On the other hand, If I have:

  foo/foo.rb

and then require 'foo', then foo/foo.rb will be loaded. I think that this is an acceptable compromise, although I'm not sure I would want it to assume that the default is "foo"; I would prefer that we come up with some sort of default -- possibly configurable (c.f. "index.html"). -- Austin Ziegler


a) it's too easy to prepare foo.rb that loads 'foo/foo.rb'. b) cnfiguring behavior in the language is a bad thing. configuration must belong to applicatins.

-- matz.


Strongly opposed 0
Opposed 0
Neutral 0
In favor 11
Strongly advocate 5
ruby picture
If you have registered at RCRchive, you may now sign in below. If you have not registered, you may sign up for a username and password. Registering enables you to submit new RCRs, and vote and leave comments on existing RCRs.
Your username:
Your password:

ruby picture

Powered by .