Are there packages?

Usually, Ruby projects use the following directory structure:
  bin/ # contains Ruby scripts which will be installed
     my_program.rb
     my_program2.rb
  lib/ # contains scripts which contain classes/modules
        # they'll be installed into /usr/local/lib/ruby/site_ruby/1.8
     my_program/
       foo.rb # contains, e.g. class MyProgram::Foo
       app.rb # contains, e.g. class MyProgram::App
  test/ # contains test scripts using Test::Unit
     test_foo.rb
     test_bar.rb

bin/my_program.rb could contain code like the following:
    require 'my_program/app'
    MyProgram::App.new.run

Note 1: If you're using modules, which is a good idea to ensure you don't
overlap the global namespace, then it's conventional to put the source for
Foo::Bar::MyClass in lib/foo/bar/myclass.rb - and therefore the user of this
class will pull it in with

    require 'foo/bar/myclass'

Note 2: the "require" filename is tried relative to each of the directories
in $LOAD_PATH; and possibly also relative to the current working directory,
if $LOAD_PATH contains ".".

But it's important to note that it is *not* relative to the location where
the file which contains the "require" line is.

So, if the code in lib/my_program/app.rb wishes to load the class in
lib/my_program/foo.rb, it should contain

  require 'my_program/foo'

and *not*

  require 'foo'

(even though 'foo.rb' is in the same directory as 'app.rb').

Note 3: if you want to run the programs in bin/ without first installing
their libraries you can do so, but you'll need to update the $LOAD_PATH
appropriately. This can be done by hand:

  cd bin
  ruby -I../lib my_program.rb

or in the outer directory:

  ruby -Ilib bin/my_program.rb

In programs in the test/ directory, I often put

  $:.unshift '../lib'

as the first line for this purpose ($: is shorthand for $LOAD_PATH). But you
still have to run them as

  cd test
  ruby test_foo.rb

rather than

  ruby test/test_foo.rb # LoadError: No such file to load -- my_program/foo

Again, this is because my_program/foo is tried relative to each of the
entries in $LOAD_PATH. We are adding an entry '../lib', which means that
'../lib/my_program/foo.rb' will be tried; but this pathname is relative to
the current working directory, so you have to 'cd' to a suitable place for
it to work.

With a bit of work, you can fix this. Something like

  $:.unshift(File.expand_path(__FILE__+"/../../lib")).uniq!

should work regardless of the current working directory:

  cd /tmp
  ruby /path/to/test/test_foo.rb
  # $LOAD_PATH contains /path/to/lib

Or, your test program can forcibly set the current working directory to the
right place when it starts:

  Dir.chdir(File.dirname(File.expand_path(__FILE__)))
  $:.unshift("../lib")

If anybody has a simpler solution than this, I'd be interested to see it.

Regards,

Brian.

Note 3: if you want to run the programs in bin/ without first installing
their libraries you can do so, but you'll need to update the $LOAD_PATH
appropriately. This can be done by hand:

  cd bin
  ruby -I../lib my_program.rb

or in the outer directory:

  ruby -Ilib bin/my_program.rb

It's often desirable to add both directories to the path, especially with testing (Test Suites load Test Cases probably in the same directory). The -I option can handle this too:

ruby -I lib:test test/ts_all.rb

If anybody has a simpler solution than this, I'd be interested to see it.

I used to muck with $: as you showed, then I discovered the wonderful world of Rake. Most of the tasks will just do the right thing. For example, here's the equivalent of my test example above:

require "rake/testtask"

task :default => [:test]

Rake::TestTask.new do |test|
     test.libs << "test" # "lib" is already in there
     test.test_files = [ "test/ts_all.rb" ]
     test.verbose = true
end

I guess that looks a little verbose, but with the above running my tests is as simple as:

$ rake

And Rake is handy for SO much more. I've gotten into the habit of making a task for everything. I have tasks that generated a project's documentation with RDoc, then move it up to Rubyforge for me.

It took me maybe 30 minutes to get comfortable with Rake and I haven't mucked with $: since. (When I'm building my own tasks I use -I all:the:directories:i:need, as shown above.) I think it was time well spent.

Hope that helps.

James Edward Gray II

···

On Jul 22, 2005, at 7:48 AM, Brian Candler wrote:

There's a few other environmental variables to consider
re:search/execution paths, see table on p.182, pickaxe2:

RUBYLIB: additional search paths to be searched after $LOAD_PATH or $:
if $SAFE == 0

Also, note that rub does *not* add your current script's directory to
the execution path (like python does), so you'll often see something
like:

require File.dirname(__FILE__) + '/../moduleInArbitraryLocation'

see also RUBYPATH, RUBYLIB_PREFIX (win32). Also note that you can't
make permanent changes to $PATH or other environmental vars on your win
or unix box by issuing command such as ENV['TERM']=whatever. If you
write to ENV['TERM'], those changes are local to the process.

James Edward Gray II wrote:

Note 3: if you want to run the programs in bin/ without first installing
their libraries you can do so, but you'll need to update the $LOAD_PATH
appropriately. This can be done by hand:

  cd bin
  ruby -I../lib my_program.rb

or in the outer directory:

  ruby -Ilib bin/my_program.rb

It's often desirable to add both directories to the path, especially
with testing (Test Suites load Test Cases probably in the same
directory). The -I option can handle this too:

ruby -I lib:test test/ts_all.rb

If anybody has a simpler solution than this, I'd be interested to see
it.

I used to muck with $: as you showed, then I discovered the wonderful
world of Rake. Most of the tasks will just do the right thing. For
example, here's the equivalent of my test example above:

Here's another approach that I have been very happy with. First, some
one-time-only setup:

$ mkdir ~/prj # base dir for your projects
$ mkdir ~/prj/lib # this will contain some symlinks
$ export RUBYLIB=~/prj/lib

Now, each time you start a new project, foo, you probably do something
like this, to give it the standard project structure for using install.rb:

$ cd ~/prj
$ mkdir foo
$ mkdir foo/lib
$ mkdir foo/lib/foo
$ touch foo/lib/foo.rb
$ touch foo/lib/foo/bar.rb

Here's the additional work so you can require this project's files.

$ cd ~/prj/lib
$ ln -s ../foo/lib/foo .
$ ln -s ../foo/lib/foo.rb .

The advantages of this setup are:

1. You can require the files using just:

  require 'foo' # loads ~/prj/foo/lib/foo.rb
  require 'foo/bar' # loads ~/prj/foo/lib/foo/bar

(and this is the same way users who install your lib on their systems
using the standard install.rb will do it).

2. No extra command line options.

3. Independent of other tools.

4. Only one modification of RUBYLIB.

5. All your projects see the latest versions of each other without
having to install anything locally or remember command line arguments.

···

On Jul 22, 2005, at 7:48 AM, Brian Candler wrote:

> Note 3: if you want to run the programs in bin/ without first
> installing
> their libraries you can do so, but you'll need to update the
> $LOAD_PATH
> appropriately. This can be done by hand:
>
> cd bin
> ruby -I../lib my_program.rb
>
> or in the outer directory:
>
> ruby -Ilib bin/my_program.rb

It's often desirable to add both directories to the path, especially
with testing (Test Suites load Test Cases probably in the same
directory). The -I option can handle this too:

ruby -I lib:test test/ts_all.rb

> If anybody has a simpler solution than this, I'd be interested to
> see it.

I used to muck with $: as you showed, then I discovered the wonderful
world of Rake. Most of the tasks will just do the right thing. For
example, here's the equivalent of my test example above:

require "rake/testtask"

task :default => [:test]

Rake::TestTask.new do |test|
     test.libs << "test" # "lib" is already in there
     test.test_files = [ "test/ts_all.rb" ]
     test.verbose = true
end

I guess that looks a little verbose, but with the above running my
tests is as simple as:

$ rake

And Rake is handy for SO much more. I've gotten into the habit of
making a task for everything. I have tasks that generated a
project's documentation with RDoc, then move it up to Rubyforge for me.

It took me maybe 30 minutes to get comfortable with Rake and I
haven't mucked with $: since. (When I'm building my own tasks I use -
I all:the:directories:i:need, as shown above.) I think it was time
well spent.

I've recenlty poked my nose into Rake, and it looked like it could be
very handy, but I've yet to find the right docs/tutorial to get me to
the point where I "get" it. Could be that I'm trying to use it with
another language, dunno.

Thought it might also be handy to develop libraries in a lib dir
that's under a project dir, then use Rake to install them under
site_ruby so they'd be available for other projects. Cuts down on
file system nav while I'm building it, and I'd end up with an install
file to hand out to others.

anyway, if anybody knows of tutorials/examples that aren't so
c-oriented, I'd love to see them.

···

On 7/22/05, James Edward Gray II <james@grayproductions.net> wrote:

On Jul 22, 2005, at 7:48 AM, Brian Candler wrote:

Hope that helps.

James Edward Gray II

--
Bill Guindon (aka aGorilla)

Bill Guindon said:

I've recenlty poked my nose into Rake,

[...]

anyway, if anybody knows of tutorials/examples that aren't so
c-oriented, I'd love to see them.

I'm planning on doing some non-c examples soon. This just encourages me
to do it sooner. :slight_smile:

Do you have something in particular in mind?

···

--
-- Jim Weirich jim@weirichhouse.org http://onestepback.org
-----------------------------------------------------------------
"Beware of bugs in the above code; I have only proved it correct,
not tried it." -- Donald Knuth (in a memo to Peter van Emde Boas)

Bill Guindon said:
> I've recenlty poked my nose into Rake,
[...]
> anyway, if anybody knows of tutorials/examples that aren't so
> c-oriented, I'd love to see them.

I'm planning on doing some non-c examples soon. This just encourages me
to do it sooner. :slight_smile:

Do you have something in particular in mind?

Sure, got stumped a couple times going through the "building with
rake" examples, I'll send you some notes off list.

···

On 7/22/05, Jim Weirich <jim@weirichhouse.org> wrote:

--
-- Jim Weirich jim@weirichhouse.org http://onestepback.org
-----------------------------------------------------------------
"Beware of bugs in the above code; I have only proved it correct,
not tried it." -- Donald Knuth (in a memo to Peter van Emde Boas)

--
Bill Guindon (aka aGorilla)