encapsulating rubygems so that my users don't need to be aware of it

C

Csaba Henk

Hi!

Say in appfoo I use lib_a, lib_b and lib_c.

I know if you want to use appfoo, and you have some of these libs as
gems, you can do it by inserting a "require rubygems" to the beginning
of appfoo, or running it as "ruby -rubygems <path-to-appfoo>", or by
tinkering with $RUBYOPTS.

But what if now I say *I* am aware of rubygems, and I want to let my users
not to care about whether this or that is installed as a gem or not?

One I could come up with is the following: I start apfoo like this:

%w(lib_a lib_b lib_c).each {|lib|
begin
require lib
rescue LoadError
require rubygems
require lib
end
}

-- but it's ugly, and gives a useless error message if both rubygems and
one of the libs is missing.

I also tought of

begin
require rubygems
rescue LoadError
end
require lib_a
require lib_b
require lib_c

but it pulls in rubygems unnecessarily if it's installed, but lib_* are
not gems.

The following monster:

%w(lib_a lib_b lib_c).each {|lib|
begin
require lib
rescue LoadError
begin
require rubygems
rescue LoadError
end
require lib
end
}

should work like a charm, but it's ridiculously baroque.

Any better idea?

Csaba
 
C

Csaba Henk

%w(lib_a lib_b lib_c).each {|lib|
begin
require lib
rescue LoadError
begin
require rubygems
rescue LoadError
end
require lib
end
}

%w(lib_a lib_b lib_c).each {|lib|
begin
require lib
rescue LoadError
begin
require rubygems
rescue LoadError
end and retry
end
}

is slightly better, maybe.

Csaba
 
J

Joel VanderWerf

Csaba said:
%w(lib_a lib_b lib_c).each {|lib|
begin
require lib
rescue LoadError
begin
require rubygems
rescue LoadError
end and retry
end
}

is slightly better, maybe.

Is testing the return value of require what you want?
#require returns false if the lib was already loaded.
 
A

Assaph Mehr

else true # this is also needed here...

If the user has *no* version of the lib (i.e. not the gem and not the
regular version) you would get into an infinite loop here.


In Instiki/Pimki we tackle this like so: the tgz includes the libs
needed, while the gem version does not but does specify them as
dependencies. When starting we test if this is a gem or not and know
how to require the necessary libs. Does this help?

Cheers,
Assaph
 
C

Csaba Henk

Is testing the return value of require what you want?
#require returns false if the lib was already loaded.

Yes, you are right. I've already posted the correction.

Csaba
 
C

Csaba Henk

If the user has *no* version of the lib (i.e. not the gem and not the
regular version) you would get into an infinite loop here.

Again, the critique is correct. Then forget all except my first and
current post in this thread, and look at the one called "monster" in the
first post. That does the job...
In Instiki/Pimki we tackle this like so: the tgz includes the libs
needed, while the gem version does not but does specify them as
dependencies. When starting we test if this is a gem or not and know
how to require the necessary libs. Does this help?

Well, maybe I'll choose a different distribution scheme, but that's not
the heart of the matter.

The problem is that if you want to shield your users from package
mana-gem-ent issues, you have to add clutter to your code, this way or
that. As I read, you are doing this as well. I'm just looking for a
somewhat "lite" or elegant solution. No dice yet.

Maybe we have to live with it, until gems are either embraced properly
and will be integrated into official ruby or will be completely
discarded. This hanging-in-the-middle state is somewhat weird.

Csaba
 
A

Assaph Mehr

Again, the critique is correct. Then forget all except my first and
current post in this thread, and look at the one called "monster" in the
first post. That does the job...

D'oh! Should have read in time order...
Well, maybe I'll choose a different distribution scheme, but that's not
the heart of the matter.

The problem is that if you want to shield your users from package
mana-gem-ent issues, you have to add clutter to your code, this way or
that. As I read, you are doing this as well. I'm just looking for a
somewhat "lite" or elegant solution. No dice yet.

Ha! Wait until you get into mismatching gem version management. You
_have_ to specify the version of the gem you want, otherwise clients
might have a wrong version. Seriously, see who your users are. If you
think you need to encapsulate as much as possible (i.e. non developers
:) then I think it's best to ship together those versions you can
trust to work with your app.

If you ever come across a better scheme (especially a lite one :),
share it with the world! There are lots of us who'd love to know.
Maybe we have to live with it, until gems are either embraced properly
and will be integrated into official ruby or will be completely
discarded. This hanging-in-the-middle state is somewhat weird.

I think Matz is inclined to do so in the future (especially now that
RPA seems to have slowed down somewhat), but that is in the far future
probably.

Cheers,
Assaph
 
C

Csaba Henk

Ha! Wait until you get into mismatching gem version management. You
_have_ to specify the version of the gem you want, otherwise clients
might have a wrong version. Seriously, see who your users are. If you
think you need to encapsulate as much as possible (i.e. non developers
:) then I think it's best to ship together those versions you can
trust to work with your app.

If you ever come across a better scheme (especially a lite one :),
share it with the world! There are lots of us who'd love to know.

Thanks... at least I'm assured that in this case not I'm the one who
doesn't see the light... so we can say, "it helped" :)

Csaba
 

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
474,169
Messages
2,570,919
Members
47,460
Latest member
eibafima

Latest Threads

Top