# Code organisation "template" interference(?) with RUBYLIB en

**URL:** <https://www.ruby-forum.com/t/code-organisation-template-interference-with-rubylib-en/88358>\
**Category:** Ruby\
**Created:** [March 10, 2007, 12:25am UTC](https://www.ruby-forum.com/t/code-organisation-template-interference-with-rubylib-en/88358 "2007-03-10T00:25:30Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![casper\_the\_ghost](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/58956e/32.png) [@casper\_the\_ghost](https://www.ruby-forum.com/u/casper_the_ghost)\
**Post date:** [March 10, 2007, 12:25am UTC](https://www.ruby-forum.com/t/code-organisation-template-interference-with-rubylib-en/88358/1 "2007-03-10T00:25:30Z")

</div>

(Warning: this post is waaaaay longer than I intended)

Hello,

Apologies if the subject line is a bit cryptic, but it’s not easy to  
describe in a single  
line. Anyway…

A while back an astute fellow on comp.lang.ruby (thanks RobertK!)  
provided me with some  
advice on how to lay out ruby classes and code that ended up being so  
useful that I’ve  
applied the same organisational template for several projects. I may  
have butchered the  
advice, but basically I have the following sort of setup (apologies for  
the lengthy ASCII  
art too),

—project1 (module Proj1)  
| |–lib  
| | |—project1.rb (class Proj1::Runner)  
| | |—config  
| | | |  
| | | `--config.rb (class Proj1::Config) | | |---base | | | | | | |`–base.rb (class Proj1::Base)  
| | |—runner1 (module Proj1::Runner1)  
| | | |  
| | | |–base.rb (class Proj1::Runner1::Base \< Proj1::Base)  
| | | |–runner1.rb (class Proj1::Runner1::Runner \<  
Proj1::Runner1::Base)  
| | | |–class1.rb (class Proj1::Runner1::Class1 \<  
Proj1::Runner1::Base)  
| | | |–class2.rb (class Proj1::Runner1::Class2 \<  
Proj1::Runner1::Base)  
| | | …etc  
| | `---runner2 (== module Runner2) | | | | | |--base.rb (class Proj1::Runner2::Base < Proj::Base) | | |--runner2.rb (class Proj1::Runner2::Runner < Proj1::Runner2::Base) | | |--class1.rb (class Proj1::Runner2::Class1 < Proj1::Runner2::Base) | | |--class2.rb (class Proj1::Runner2::Class2 < Proj1::Runner2::Base) | | ...etc | |--test | | | | ...etc | |-project2 (module Proj2) | |--lib | | |---project2.rb (class Proj2::Runner) | | |---config | | | | | | |`–config.rb (class Proj2::Config)  
| | |—base  
| | | |  
| | | `--base.rb (class Proj2::Base) | | |---runner1 (module Proj2::Runner1) | | | | | | | |--base.rb (class Proj2::Runner1::Base < Proj2::Base) | | | |--runner1.rb (class Proj2::Runner1::Runner < Proj2::Runner1::Base) | | | |--class1.rb (class Proj2::Runner1::Class1 < Proj2::Runner1::Base) | | | |--class2.rb (class Proj2::Runner1::Class2 < Proj2::Runner1::Base) | | | ...etc | |`—runner2 (== module Runner2)  
| | |  
| | |–base.rb (class Proj2::Runner2::Base \< Proj2::Base)  
| | |–runner2.rb (class Proj2::Runner2::Runner \<  
Proj2::Runner2::Base)  
| | |–class1.rb (class Proj2::Runner2::Class1 \<  
Proj2::Runner2::Base)  
| | |–class2.rb (class Proj2::Runner2::Class2 \<  
Proj2::Runner2::Base)  
| | …etc  
| |–test  
| | |  
…etc

etc.

For any project, call it module ProjectX:

- the lib/projectX.rb file (class Project2::Runner) is the interface to  
a  
user. It’s the “main” runner class if you like.

- the ProjectX::Config class holds, surprise, all the configuration info  
(usually read in from a text file)

- the ProjectX::Base clase holds all the constants and methods that are  
shared throughout any particular ProjectX module

- the ProjectX::RunnerY::Base class holds all the constants and methods  
that are shared throughout any particular ProjectX::RunnerY module

- the ProjectX::RunnerY::Runner class is the controller that iterates  
over  
all the current module classes (the Class1, Class2,…ClassZ etc) and  
invokes their methods

- the ProjectX::RunnerY::ClassZ class actually does something. :o)

I like the above setup because it scales quite well. For some projects  
each “runnerY”  
contains another layer. It’s made it really easy to isolate  
functionality and test it.

Anyway, the problem I’m having now is I decided to consolidate all my  
code on a single  
machine and tack on the various locations of everything onto the RUBYLIB  
envar, i.e.

export RUBYLIB=$HOME/ruby/project1/lib:$HOME/ruby/project2/lib: etc…

So now when I do something like the following in  
project2/lib/runner1/base.rb,

require ‘base/base’  
module Proj2  
module Runner1  
class Base \< Proj2::Base  
# This is how the config gets passed along in  
# Runner1 module and holds shared Runner1 code  
end  
end  
end

and in project2/lib/runner1/runner.rb,

require ‘runner1/base’  
module Proj2  
module Runner1  
class Runner \< Proj2::Runner1::Base  
RUNNERS=[Class1,Class2,…,ClassZ]  
def run  
RUNNERS.each do |run\_class|  
r = run\_class.new  
r.config = self.config  
r.run  
end  
end  
end  
end  
end

and invoke the main script, ruby searches the RUBYLIB paths and finds  
the “base/base.rb”  
for project_1_ first (since it’s listed first) and loads that file  
instead of the  
“base/base.rb” for project_2_. Thus, I get errors like:

project2/lib/runner1/base.rb:4: uninitialized constant Project2::Base  
(NameError)

If I swap the listing in my RUBYLIB envar so that the project2 directory  
is listed first,  
everything is honky dory and runs fine.

Phewph! If you’ve made it this far, the beer is on me if we ever meet.

My questions are:

1. can I keep my current directory structure (which, believe it or not,  
seems quite  
logical to me) and avoid these file loading order problems?

2. IF not, how to fix this? I like the idea of generic file names and  
classes (config,  
base) across projects so that those that follow can grok multiple  
projects after studying  
the docs for just one.

Thanks for any insight.

cheers,

paulv

---

<div class="post-metadata">

**Author:** ![casper\_the\_ghost](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/58956e/32.png) [@casper\_the\_ghost](https://www.ruby-forum.com/u/casper_the_ghost)\
**Post date:** [March 10, 2007, 3:49pm UTC](https://www.ruby-forum.com/t/code-organisation-template-interference-with-rubylib-en/88358/2 "2007-03-10T15:49:58Z")

</div>

On Sat, Mar 10, 2007 at 08:25:09AM +0900, Paul van Delst wrote:

> —project1 (module Proj1)  
> | |–lib  
> | | |—project1.rb (class Proj1::Runner)  
> | | |—config  
> | | | |  
> | | | `–config.rb (class Proj1::Config)  
> …  
> require ‘base/base’  
> module Proj2  
> module Runner1

I’d suggest putting a single entry in your load path, for the very top  
level  
of your directory structure, and then use

require ‘project1/lib/base/base’

instead of

require ‘base/base’

This is the simplest way of easily distinguishing project1 from project2  
if  
the subdirectories and files contained by both have the same names  
(especially if project1 needs to use files within project2)

If all projects are independent, then clearly when you run an  
application  
from project1 you only need to put project1’s lib directory into the  
RUBYLIB  
environment.

If you want to automate this, then create a bunch of files at the top  
level  
of your lib tree

[project1.rb]  
$:.unshift “/path/to/project1/lib”

[project2.rb]  
$:.unshift “/path/to/project2/lib”

Then your programs can say:

require ‘project1’  
require ‘base/base’

or whatever. (That means you only need to put one extra line at the top  
of  
each source file)

Just a couple of ideas.

B.

---

<div class="post-metadata">

**Author:** ![casper\_the\_ghost](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/58956e/32.png) [@casper\_the\_ghost](https://www.ruby-forum.com/u/casper_the_ghost)\
**Post date:** [March 12, 2007, 3:25pm UTC](https://www.ruby-forum.com/t/code-organisation-template-interference-with-rubylib-en/88358/3 "2007-03-12T15:25:46Z")

</div>

Brian C. wrote:

> > module Runner1  
> > This is the simplest way of easily distinguishing project1 from project2 if  
> > the subdirectories and files contained by both have the same names  
> > (especially if project1 needs to use files within project2)

Hi Brian,

Your suggestion is how I first thought about “fixing” my problem. But  
when other folks  
check out my code from the repository, they may not have the same  
directory structure as I  
do. Then I get calls about files not found etc.

> [project2.rb]  
> $:.unshift “/path/to/project2/lib”
> 
> Then your programs can say:
> 
> require ‘project1’  
> require ‘base/base’
> 
> or whatever. (That means you only need to put one extra line at the top of  
> each source file)

Thanks for the tip. I think I’ll look into this… I do something like  
this for my test cases.

cheers,

paulv

---

<div class="post-metadata">

**Author:** ![casper\_the\_ghost](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/58956e/32.png) [@casper\_the\_ghost](https://www.ruby-forum.com/u/casper_the_ghost)\
**Post date:** [March 12, 2007, 3:51pm UTC](https://www.ruby-forum.com/t/code-organisation-template-interference-with-rubylib-en/88358/4 "2007-03-12T15:51:50Z")

</div>

Brian C. wrote:

> require ‘project1’  
> require ‘base/base’
> 
> or whatever. (That means you only need to put one extra line at the top of  
> each source file)

Hi again,

I just tried adding

$:.unshift File.join(File.dirname( **FILE** ))

to the “parent” file and it works a treat!

I should’ve figured it out on my own, but thanks muchly for the  
hint/nudge-in-right-direction. :o)

cheers,

paulv
