On Tue, Jan 5, 2010 at 3:36 AM, Brian Candler <b.candler / pobox.com> wrote:
> Eric Christopherson wrote:
>> 1. The original Mysql class is installed as a gem. Should my extension
>> use rb_require("rubygems")? Or is requiring rubygems the
>> responsibility of the scripts that use it?
>
> In my opinion, you should not use rb_require("rubygems"). If your
> extension is packaged as a gem, then clearly rubygems will be enabled
> already; if your extension is being loaded outside rubygems, then I
> think it's the user's responsibility to require rubygems.
>
> It annoys me when I build a system where all the libraries are
> 'vendorised' locally, and one of them insists on doing a require
> 'rubygems' which I neither need nor want. But to be fair, this is a
> mistake I've made myself in the past.

That makes sense. It is possible to install mysql (and I would imagine
all or most other gems) directly in a site directory, rather than as
gems, so it doesn't make sense to require rubygems outright.

>
>> 2. Why doesn't rb_require("mysql") work?
>
> You haven't shown the exception, but my guess is that rb_require hooks
> in at a lower level which bypasses all the fudging that rubygems does
> with load_paths.
>
> You could prove this using something like (untested):
>
> rb_require('rubygems');
> rb_eval_string('gem "mysql"');
> rb_require('mysql');
>
> However that defeats (1).
>
> It might be cleaner to use one of the rb_funcall variants to to
> send(:require,"mysql") instead of rb_eval_string.

Oh, thanks for that. I would send that to the _main_ object. After
some digging, it appears that that is assigned to the variable
ruby_top_self (which isn't declared in a header), so I did this:

    EXTERN VALUE ruby_top_self;
    ...
    rb_funcall(ruby_top_self, rb_intern("send"), 2,
ID2SYM(rb_intern("require")), rb_str_new2("mysql"));

This also works:

    rb_funcall(ruby_top_self, rb_intern("require"), 1, rb_str_new2("mysql"));

Why would one want to use send rather that calling require directly?

>
>> 3. Is there one best way to get the class object for a class specified
>> by a C string? I've seen both rb_const_get(rb_cObject,
>> rb_intern("Classname")) and rb_path2class("Classname") and wonder if
>> they have any practical differences.
>
> Looking at the source of rb_path2class (in variable.c), it has built-in
> ability to follow namespaces, i.e. rb_path2class("Foo::Bar") should
> work. Otherwise, you can see it just does rb_const_get_at itself,
> starting at rb_cObject.

OK.

Thanks!