EventMachine-LE
EventMachine-LE copied to clipboard
LE may not be activated in the presence of eventmachine in some circumstances
Short version: Depending on the order in which gems are activated, it is possible to end up in the situation where eventmachine
is preferred over eventmachine-le
, causing much wailing and gnashing of teeth. Modifying eventmachine-le.rb
to include $LOAD_PATH.delete_if { |d| d =~ /\/eventmachine-\d/ }
before require 'eventmachine'
fixes things, although there's possibly a more graceful way.
Longer version: When a gem is activated, all its dependencies are activated too. This means that if you have any gems that depend on eventmachine
, then it will end up in $LOAD_PATH
, likely before any require
statements (such as require 'eventmachine-le'
) are run.
The order of the entries in $LOAD_PATH
is "last-activated-first" -- that is, if a gem activates eventmachine-le
before it activates a gem that depends on eventmachine
, then eventmachine
wins, and eventmachine-le
's code never gets loaded.
To complete the trifecta, running gem 'eventmachine-le'
when eventmachine-le
has already been activated does nothing -- it'd be nice if it "promoted" that gem's load paths to the first entries in $LOAD_PATH
, but unfortunately, it does not.
Hi, that is supposed to be documented in the README:
- https://github.com/ibc/EventMachine-LE#usage
Is that wrong? I would not like to mangle $LOAD_PATH
...
The README isn't wrong, per se -- as long as the eventmachine
gem hasn't already been activated, what's in the README will work just fine. Unfortunately, when a gem gets activated, all its dependencies get activated, and so if you activate a gem which depends on eventmachine, it'll end up in the load path. If you happened to previously activate eventmachine-le (say, because you activated a gem which depends on it -- such as the gem you're running your command from) then eventmachine will be used, not eventmachine-le.
Non-load-path-mangling alternatives are fairly thin on the ground. If you wanted to drop 1.8 support, you could use require_relative
everywhere throughout; that would solve the problem. You could temporarily mangle the load path, by unshifting the eventmachine-le gem directory onto the load path, requiring eventmachine, and then shifting it back off again afterwards. They're the only options I can think of at the moment.
Non-load-path-mangling alternatives are fairly thin on the ground. If you wanted to drop 1.8 support, you could use |require_relative| everywhere throughout; that would solve the problem. You could temporarily mangle the load path, by unshifting the eventmachine-le gem directory onto the load path, requiring eventmachine, and then shifting it back off again afterwards. They're the only options I can think of at the moment.
We could define a "require_relative_ele" that simply maps to require_relative on a modern Ruby and employs load-path mangling on 1.8.
Grüße, Carsten
You could also just re-implement require_relative
if it isn't already defined; that would involve no load path mangling.
VALUE
rb_f_require_relative(VALUE obj, VALUE fname)
{
VALUE base = rb_current_realfilepath();
if (NIL_P(base)) {
rb_raise(rb_eLoadError, "cannot infer basepath");
}
base = rb_file_dirname(base);
return rb_require_safe(rb_file_absolute_path(fname, base), rb_safe_level());
}
Should not be difficult to implement in Ruby :)
The problem however are all those EM libraries that depend on EM. They should not.
Well, until Rubygems has a concept of either "virtual packages" or "OR" dependencies, it's a bit hard for a gem to declare a dependency in a way other than on eventmachine -- unless you're talking about going round and convincing every gem to depend on eventmachine-le instead... <grin>
for future readers of this ticket the fix we've put in place is slightly different from @mpalmer's:
$LOAD_PATH.delete_if { |p| p.to_s =~ /eventmachine-\d/ }
The $LOAD_PATH
can be a Pathname