Best practice to require external code dependency ?

B

Bernard Lambeau

[Note: parts of this message were removed to make it a legal post.]

Hi Rubyist,

I'm trying to summarize what I've read about requiring external code
dependencies/gems without making wrong assumptions about the environment:

* https://gist.github.com/54177
* http://weblog.rubyonrails.org/2009/9/1/gem-packaging-best-practices

I've end up with the following method:

https://github.com/blambeau/noe/blob/master/lib/noe/loader.rb

Do you see "enhancement of" / "agreement about" such a pattern? Any reading
I should further read ??

Thanks
B
 
L

Luis Lavena

Do you see "enhancement of" / "agreement about" such a pattern? Any reading
I should further read ??

Use plain require.

If you're working from Rake, which is already a gem, it will load
rubygems so no need for you to do the require.

Also, having gem 'abc', '>= 0' is the same as doing the require of
that gem directly (it will always load the latest version), having
'gem' in your code makes it already dependent on RubyGems, which
breaks the statements in your first link.

I normally don't define any gem method in my libraries since my
dependencies will be loaded with the require (in case I'm creating a
gem that depends on other, RubyGems will active these dependencies
before I do require)
 
B

Bernard Lambeau

[Note: parts of this message were removed to make it a legal post.]

Thanks Luis,

* If I write a pure library, your answer makes sense as the dependencies
will be managed as you say.
* The same is true when the code is invoked by rake, ok.
* What if I have a bin/foo executable? Should I make something special there
if I have version requirements on external libs ??

Thanks again!
B
 
L

Luis Lavena

* What if I have a bin/foo executable? Should I make something special there
if I have version requirements on external libs ??

Actually no.

RubyGems will wrap your bin/foo script with a loader that looks like
this:

require 'rubygems'

version = ">= 0"

if ARGV.first =~ /^_(.*)_$/ and Gem::Version.correct? $1 then
version = $1
ARGV.shift
end

gem 'mygem', version
load Gem.bin_path('mygem', 'foo', version)

So your foo script don't need to require rubygems.

And when developing, if you run through rspec, it will already load
rubygems for you.

If you want to test from the command line, then you can:

ruby -rrubygems -Ilib bin/foo

Or simple put RUBYOPT=-rrubygems

and have ruby -Ilib bin/foo

So, under your environment will have rubygems and nowhere in your
code.
 
B

Bernard Lambeau

[Note: parts of this message were removed to make it a legal post.]

I see (I was currently re-reading https://gist.github.com/54177, which is
clear in fact -- my apologies).

I understand that users of my library will have a good _foo_ executable that
works fine :)

Now, as a developer I would like to be able to run (no rake, no rspec, and
so on):

ruby -rrubygems bin/foo

How are version requirements met in that scenario? I assume they are not and
that rubygems will load last versions of all gems?

Should I configure rvm's gemsets on my devel computer ? or do you use
Bundler to manage that case ??

Thanks again for clarification!
B
 
L

Luis Lavena

[Note:  parts of this message were removed to make it a legal post.]

I see (I was currently re-readinghttps://gist.github.com/54177, which is
clear in fact -- my apologies).

I understand that users of my library will have a good _foo_ executable that
works fine :)

Now, as a developer I would like to be able to run (no rake, no rspec, and
so on):

    ruby -rrubygems bin/foo

How are version requirements met in that scenario? I assume they are not and
that rubygems will load last versions of all gems?

They are not. Up to you deal with the dependencies.
Should I configure rvm's gemsets on my devel computer ? or do you use
Bundler to manage that case ??

Don't add bundler code to your library either, as bundler depends on
RubyGems, you can:

ruby -rrubygems -rbundler/setup bin/foo

Above line will work on 1.9, but not on Ruby 1.8.x

Either you need a wrapper script to do this:

ruby -Ilib -rrubygems -e "require 'bundler/setup'; load 'bin/foo'"

I can't comment more on Bundler as I don't use it, sorry.
 
B

Bernard Lambeau

[Note: parts of this message were removed to make it a legal post.]

Thanks a lot Luis, it makes things a lot clearer for me!!

For the sake of history, the initial code I was refering to in my first
message is now here:

https://gist.github.com/779830

B

[Note: parts of this message were removed to make it a legal post.]

I see (I was currently re-readinghttps://gist.github.com/54177, which is
clear in fact -- my apologies).

I understand that users of my library will have a good _foo_ executable that
works fine :)

Now, as a developer I would like to be able to run (no rake, no rspec, and
so on):

ruby -rrubygems bin/foo

How are version requirements met in that scenario? I assume they are not and
that rubygems will load last versions of all gems?

They are not. Up to you deal with the dependencies.
Should I configure rvm's gemsets on my devel computer ? or do you use
Bundler to manage that case ??

Don't add bundler code to your library either, as bundler depends on
RubyGems, you can:

ruby -rrubygems -rbundler/setup bin/foo

Above line will work on 1.9, but not on Ruby 1.8.x

Either you need a wrapper script to do this:

ruby -Ilib -rrubygems -e "require 'bundler/setup'; load 'bin/foo'"

I can't comment more on Bundler as I don't use it, sorry.
 

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

Forum statistics

Threads
473,981
Messages
2,570,188
Members
46,732
Latest member
ArronPalin

Latest Threads

Top