Forum: Ruby Re: Code organisation "template" interference(?) with RUBYLI

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
Joseph Schiller (Guest)
on 2007-03-10 01:54
(Received via mailing list)
Hi,

If you don't need ADMIN rights to shuffle files from place to place, you
might want to point your browser to http://www.obsession.se/gentoo and
give gentoo file manager a try.  It is fast and has all the features
conveniently in one place.  It appears that you are trying to manage a
graphical IDE style hierarchy that may not easily accomodate a complex
file structure. I don't know if there is a single solution, one approach
from Debian is managing different versions of software using
/etc/alternatives. You can write a simple bash script to integrate
files. I would not recommend setting env vars for every project, env
should rather accomodate lib or system files. I would much rather have
one system-wide config across different projects.

Regards,

Joe

----- Original Message ----
From: Paul van Delst <removed_email_address@domain.invalid>
To: ruby-talk ML <removed_email_address@domain.invalid>
Sent: Friday, March 9, 2007 6:25:09 PM
Subject: Code organisation "template" interference(?) with RUBYLIB envar

(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

--
Paul van Delst             Ride lots.
CIMSS @ NOAA/NCEP/EMC               Eddy Merckx
Paul van Delst (Guest)
on 2007-03-12 16:35
(Received via mailing list)
Joseph Schiller wrote:
> rather have one system-wide config across different projects.
Hi Joe,

Thanks for the input, but the projects run on a bunch of different
platforms -- various
flavours of linux and various flavours of IBM AIX. The red tape involved
for me to install
something like the gentoo file manager on all of these systems (assuming
that's possible)
is...well... I can't even think of a suitable adjective! :o)

Thanks for the info.

cheers,

paulv
This topic is locked and can not be replied to.