Packaging - distribution

P

Pito Salas

I am looking for best practices for using a multi-file body of ruby code
within a different multi-file body of ruby code.

In other words, let's say I have this:

system/
stand_alone_sub.rb
lib/
sub_alpha.rb
sub_bravo.rb

System is a nice program which runs by invoking stand_alone_sub.rb. Ah,
but now I have a new application:

newapplication/
na.rb
lib/
na_charlie.rb
na_delta.rb

And in na_delta I want to use the functionalities from 'system' above.

I have a few choices, I guess:

1) make system/ into a gem. I don't love this because it implies to me
that it's a general purpose service, and maybe it is, but off the cuff
it feels like overkill.

2) combine system/ and newapplication/ into one application. I don't
like this because they are separate and while one depends on the other,
the first is useful on its own.

3) copy the files from system/ into a subdirectory under newapplication.
And keep the files in sync. I don't like this because of many reasons.

4) Somehow be clever with the search paths when invoking system/ from
newapplicaiton/ I don't like this because I am not sure how to do it and
I fear it will not be robust

5) What else?

Any comments?

Thanks!

Pito
 
D

David Masover

1) make system/ into a gem. I don't love this because it implies to me
that it's a general purpose service, and maybe it is, but off the cuff
it feels like overkill.

If you've never built a gem before, now is a good time to start. The hardest
part is picking a name. After that, it's really not as scary as people make it
out to be.
2) combine system/ and newapplication/ into one application. I don't
like this because they are separate and while one depends on the other,
the first is useful on its own.

If this is for public consumption, the question to ask is whether anyone would
want system who didn't also want newapplication. If not, you could simply move
system into a subdirectory of newapplication, and let people use it as needed.
3) copy the files from system/ into a subdirectory under newapplication.
And keep the files in sync. I don't like this because of many reasons.

Git submodules could make this work very well. As a bonus, newapplication
would always depend on a specific version of system, just like it could with a
gem.
4) Somehow be clever with the search paths when invoking system/ from
newapplicaiton/ I don't like this because I am not sure how to do it and
I fear it will not be robust

"Not robust", maybe. But if newapplication always knows where system is, it's
easy:

$: << '/path/to/system/lib'
require 'sub_alpha'

In my opinion, that's much better than trying to do something like:

require '/path/to/system/lib/sub_alpha.rb'
 
P

Pito Salas

David,

Thanks for a sensational answer to my question! Great detail, very
informative.
$: << '/path/to/system/lib'
require 'sub_alpha'

In my opinion, that's much better than trying to do something like:

require '/path/to/system/lib/sub_alpha.rb'

I've seen the $: << construct; can you say a little about why it's much
better than putting the path directly in the require?

My guess is that the path appears only once in the $: line so if it
changes you don't have to go changing a whole bunch of requires. Yes, or
is there something else more important?

Thanks

- Pito
 
B

Brian Candler

Pito said:
David,

Thanks for a sensational answer to my question! Great detail, very
informative.


I've seen the $: << construct; can you say a little about why it's much
better than putting the path directly in the require?

My guess is that the path appears only once in the $: line so if it
changes you don't have to go changing a whole bunch of requires. Yes, or
is there something else more important?

If one bit of code does "require 'sub_alpha'", and another bit of code
does "require '/path/to/system/lib/sub_alpha'", then the file will be
loaded twice.

So you may see this pattern:

require File.dirname(__FILE__)+"/../lib/sub_alpha"

but I'd strongly recommend against it.

BTW, $:.unshift is probably better than $: <<, because it will put your
code at the front of the path.
 
A

Aaron Patterson

If one bit of code does "require 'sub_alpha'", and another bit of code
does "require '/path/to/system/lib/sub_alpha'", then the file will be
loaded twice.

Can I suggest that someone doing a require using the entire path is
Doing It Wrongâ„¢? They should be properly adjusting their load path with
-I. Specifying a full path is like saying "Hey Ruby and Rubygems, I
either don't understand how load paths work, or I don't trust you to do
your job!".
So you may see this pattern:

require File.dirname(__FILE__)+"/../lib/sub_alpha"

but I'd strongly recommend against it.

BTW, $:.unshift is probably better than $: <<, because it will put your
code at the front of the path.

Mucking with the load path is bad and is not the responsibility of your
script. The include path should be set up by Ruby, Rubygems, or
the -I flag to the ruby script IMO. Remember that when you mess with
the load path, you are modifying a global variable.
 
C

Caleb Clausen

I am looking for best practices for using a multi-file body of ruby code
within a different multi-file body of ruby code.

If you don't want to make gems, you should consider Chris Wanstrath's
rip 'package manager' as well. It let's you make a meta-package which
contains subprojects that are found in gems, git repositories, plain
directories, tarballs(?), etc.

I have a little script of my own that I made to solve this kind of
problem, but it's not published. Email me if you're really interested,
I'll send it to you.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,774
Messages
2,569,598
Members
45,147
Latest member
CarenSchni
Top