Packaging - distribution

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

On Monday 24 August 2009 05:08:58 pm Pito S. wrote:

  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.

  1. 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.

  1. 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.

  1. 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’

Pito S. wrote:

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?

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.

On 8/24/09, Pito S. [email protected] wrote:

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 W.'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.

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

On Tue, Aug 25, 2009 at 10:11:38PM +0900, Brian C. wrote:

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.

This forum is not affiliated to the Ruby language, Ruby on Rails framework, nor any Ruby applications discussed here.

| Privacy Policy | Terms of Service | Remote Ruby Jobs