# \[ANN\] Better relative requires with Need

**URL:** <https://www.ruby-forum.com/t/ann-better-relative-requires-with-need/128658>\
**Category:** Ruby\
**Created:** [February 9, 2008, 11:54pm UTC](https://www.ruby-forum.com/t/ann-better-relative-requires-with-need/128658 "2008-02-09T23:54:34Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![dfg59](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/e0b2c6/32.png) [@dfg59](https://www.ruby-forum.com/u/dfg59)\
**Post date:** [February 9, 2008, 11:54pm UTC](https://www.ruby-forum.com/t/ann-better-relative-requires-with-need/128658/1 "2008-02-09T23:54:34Z")

</div>

Need makes ruby relative requires just work. Simply need a file with a  
relative path  
and the file will always be required correctly, regardless of what file  
your application is  
being launched through. Typically, ruby projects would unshift lib onto  
$PATH or use the  
File.dirname( **FILE** ) trick. Using need means you don’t have to worry  
about either of these.

Assume you have two files, one directly in lib and the other in  
lib/extensions. Let’s assume that file\_a in lib requires file\_b, in  
lib/extensions. Previously, you would doing some crazy load path  
unshifting or use the **FILE** trick to make these requires flexible  
enough to work when your app is being accessed by rake, through a test  
suite, or required as a gem. Now, just use need.

In file\_a:  
need{“extensions/file\_b”}

Note that the block syntax is necessary. Need uses the binding of the  
block to determine the  
location of your file and correct perform your relative require for you.

== INSTALL:

- sudo gem install need

Hope you enjoy it!

- Drew

---

<div class="post-metadata">

**Author:** ![dfg59](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/e0b2c6/32.png) [@dfg59](https://www.ruby-forum.com/u/dfg59)\
**Post date:** [February 10, 2008, 12:31am UTC](https://www.ruby-forum.com/t/ann-better-relative-requires-with-need/128658/2 "2008-02-10T00:31:06Z")

</div>

On Feb 9, 2008, at 3:54 PM, Drew O. wrote:

> Note that the block syntax is necessary. Need uses the binding of the  
> block to determine the  
> location of your file and correct perform your relative require for  
> you.

nice idea!

a @ [http://drawohara.com/](http://drawohara.com/)

---

<div class="post-metadata">

**Author:** ![dfg59](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/e0b2c6/32.png) [@dfg59](https://www.ruby-forum.com/u/dfg59)\
**Post date:** [February 10, 2008, 3:42pm UTC](https://www.ruby-forum.com/t/ann-better-relative-requires-with-need/128658/3 "2008-02-10T15:42:46Z")

</div>

Kudos! I had worked on something similar although I didn’t use the  
block binding which is a better way to go. I alias\_method\_chained  
require and was using the caller stack to figure out the correct file  
path. But I kept running into the problem of having to require it  
everywhere… Like I would be in a test file and you’d have to have,

require ‘elreq’ # name of mine  
require ‘…/…/test\_helper’

So I largely gave up b/c while it was cleaner, adding the extra  
require everywhere seemed to negate the benefits. If only it was  
globally available - like in core. 🙂

A suggestion, if you are concerned with portability you may want to  
use File.join to concatenate the end result together. Also, you  
probably want to stick it in the Kernel module, but that may just be a  
design pet peeve of mine.

Glad something like this is out there.

Cheers,  
Kevin

---

<div class="post-metadata">

**Author:** ![dfg59](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/e0b2c6/32.png) [@dfg59](https://www.ruby-forum.com/u/dfg59)\
**Post date:** [February 10, 2008, 5:34pm UTC](https://www.ruby-forum.com/t/ann-better-relative-requires-with-need/128658/4 "2008-02-10T17:34:36Z")

</div>

Kevin B. wrote:

> Glad something like this is out there.
> 
> Cheers,  
> Kevin

Kevin -

Thanks so much for the response. I’m glad people may find it useful. As  
far as joining the file path, what exactly does this buy me? I’ve seen  
it used quite a bit, but never used it myself. Also, in regard to  
extending Kernel rather than Object, isn’t Kernel itself an Object? Or  
is it seen as too intrusive to extend object?

Thanks for the advice and please feel free to submit a patch, I’ll  
definitely take a look at adding it to the source.

Thanks,  
Drew

---

<div class="post-metadata">

**Author:** ![dfg59](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/e0b2c6/32.png) [@dfg59](https://www.ruby-forum.com/u/dfg59)\
**Post date:** [February 11, 2008, 2:58pm UTC](https://www.ruby-forum.com/t/ann-better-relative-requires-with-need/128658/5 "2008-02-11T14:58:57Z")

</div>

Hi,

On 10-Feb-08, at 11:34 AM, Drew O. wrote:

> As  
> far as joining the file path, what exactly does this buy me?

You can avoid the problem (leaving it entirely in the hands of your  
users) if you write it this way:

File.expand\_path(block.call,  
File.dirname(eval(“ **FILE** ”,block.binding)))

And it’s shorter.

Anyway, thanks for the gem!

Cheers,  
Bob

* * *

Bob H. – tumblelog at  
[http://www.recursive.ca/so/](http://www.recursive.ca/so/)  
Recursive Design Inc. – weblog at  
[http://www.recursive.ca/hutch](http://www.recursive.ca/hutch)  
[http://www.recursive.ca/](http://www.recursive.ca/) – works on  
[http://www.raconteur.info/cms-for-static-content/home/](http://www.raconteur.info/cms-for-static-content/home/)

---

<div class="post-metadata">

**Author:** ![dfg59](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/e0b2c6/32.png) [@dfg59](https://www.ruby-forum.com/u/dfg59)\
**Post date:** [February 11, 2008, 5:26pm UTC](https://www.ruby-forum.com/t/ann-better-relative-requires-with-need/128658/6 "2008-02-11T17:26:31Z")

</div>

On Feb 10, 2008, at 9:34 AM, Drew O. wrote:

> Thanks so much for the response. I’m glad people may find it u  
> seful. As  
> far as joining the file path, what exactly does this buy me?

i always expand and join the path because otherwise doing

require ‘…/a.rb’

followed by

require ‘…/./a.rb’

will cause ruby to load the file twice - the hash is on the _exact_  
filename

cheers.

a @ [http://drawohara.com/](http://drawohara.com/)

---

<div class="post-metadata">

**Author:** ![dfg59](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/e0b2c6/32.png) [@dfg59](https://www.ruby-forum.com/u/dfg59)\
**Post date:** [February 11, 2008, 7:04pm UTC](https://www.ruby-forum.com/t/ann-better-relative-requires-with-need/128658/7 "2008-02-11T19:04:18Z")

</div>

I believe this should be handled by ruby’s require in 1.9…so no more  
double requires based on differing file paths.

- Rob

> **[Home](https://robsanheim.com/)**
>
> Just another WordPress site

> **[Cognitect, a Nu Holdings, Ltd. Company](https://cognitect.com/)**

---

<div class="post-metadata">

**Author:** ![dfg59](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/e0b2c6/32.png) [@dfg59](https://www.ruby-forum.com/u/dfg59)\
**Post date:** [February 11, 2008, 7:28pm UTC](https://www.ruby-forum.com/t/ann-better-relative-requires-with-need/128658/8 "2008-02-11T19:28:52Z")

</div>

Kevin B. wrote:

> A suggestion, if you are concerned with portability you may want to  
> use File.join to concatenate the end result together.

Kevin -

I read up on this and it makes quite a bit of sense. I’ll patch the code  
and release a new version.

Thanks!

- Drew
