Skip to content

rb_require("rational") raises LoadError in rubinius 2.2.3 #2874

Closed
jeremyevans opened this Issue Jan 6, 2014 · 9 comments

4 participants

@jeremyevans
Rubinius member

Attempting to require the following C extension:

#include <ruby.h>

void Init_rquire(void) {
  rb_require("rational");
}

Causing the following error:

An exception occurred requiring command line files:

    no such file to load -- rational (LoadError)

Backtrace:

                          Rubinius::CodeLoader#load_error at kernel/common/code_loader.rb:440
                Rubinius::CodeLoader#resolve_require_path at kernel/common/code_loader.rb:423
                      { } in Rubinius::CodeLoader#require at kernel/common/code_loader.rb:103
                                     Rubinius.synchronize at kernel/bootstrap/rubinius.rb:137
                             Rubinius::CodeLoader#require at kernel/common/code_loader.rb:102
                             Rubinius::CodeLoader.require at kernel/common/code_loader.rb:237
                                           Kernel.require at kernel/common/kernel.rb:705
                              Rubinius(Class)#Init_rquire at rquire.so
                    Rubinius::NativeMethod.load_extension at kernel/common/native_method.rb:43
                        Rubinius::CodeLoader#load_library at kernel/delta/code_loader.rb:283
                             Rubinius::CodeLoader#require at kernel/common/code_loader.rb:130
                             Rubinius::CodeLoader.require at kernel/common/code_loader.rb:237
  Kernel(Rubinius::Loader)#gem_original_require (require) at kernel/common/kernel.rb:705
                         Kernel(Rubinius::Loader)#require at /usr/local/lib/rubinius/library/rubygems/core_ext/kernel_require.rb:55
                         { } in Rubinius::Loader#requires at kernel/loader.rb:597
                                               Array#each at kernel/bootstrap/array.rb:66
                                Rubinius::Loader#requires at kernel/loader.rb:597
                                    Rubinius::Loader#main at kernel/loader.rb:829

I believe this worked correctly in rubinius 2.1.1, and it works correctly in all versions of MRI. This breaks the usage of rubinius with dataobjects (do_mysql, do_postgres, do_sqlite3).

$ rbx -v
rubinius 2.2.3 (2.1.0 4792e746 2013-12-29 JI) [i386-openbsd]
$ uname -a
OpenBSD testcurrent.bsa.ca.gov 5.4 GENERIC.MP#152 i386
@jc00ke
Rubinius member
jc00ke commented Jan 6, 2014

Do you have rubysl-rational in your Gemfile?

If you use a bunch of other libs from stdlib, throw gem 'rubysl', :platform => :rbx in instead.

@jeremyevans
Rubinius member

I'm not using a Gemfile. With the test extension I posted, just rbx -r ./rquire is enough to trigger the bug.

@jc00ke
Rubinius member
jc00ke commented Jan 6, 2014

Do you have rubysl-rational installed then? If not, you'll need to install it, or the whole kitchen sink via gem install rubysl.

@jeremyevans
Rubinius member

Yes. rubysl-rational (and the rest of rubysl) is included with rbx 2.2.3. rbx -r rational runs without an error, it's only the capi rb_require that appears to no longer work correctly. This could be because rb_require calls Kernel.require, which doesn't load the library either.

@headius
headius commented Jan 14, 2014

rb_require is the lower-level require that only sees files currently in load path. It does not hit the higher-level require patched in place by RubyGems which can activate gems on the fly as needed.

You'll have to invoke the patched Kernel.require method dynamically so the RubyGems version runs and activates standard libraries that are not standard anymore on Rubinius. Activating the gem ahead of time with "gem" function may also work, but would be incompatible with Ruby impls that haven't moved stdlib to gems.

@jeremyevans
Rubinius member

I think if all of the stdlib has moved to gems, then rb_require could never work as expected to in other ruby implementations. If rubinius wants to be compatible, it should probably have the rb_require capi function use Kernel.require. rb_require is not used internally in rubinius (I'm guessing), and exists solely for C extension compatibility, so I would think such a change makes sense.

@ghost
ghost commented Jan 14, 2014

that makes sense to me @jeremyevans.

@headius
headius commented Jan 14, 2014

@jeremyevans Yeah, @enebo and I were just discussing that same possibility. It would be a visible behavioral change, since the C API require could trigger gem loading, but stdlib gemification has already resulted in a broad range of visible behavioral changes on Rubinius. This may be par for the course.

@YorickPeterse
Rubinius member

Closing this one as this appears to be working on Rubinius master. rb_require does use Kernel.require, so any Gems available should be loadable using the former. Feel free to re-open if needed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.