Forum: Ruby-core [ruby-trunk - Bug #7424][Open] an embedded Ruby interpreter doesn't get the full Ruby environment un

Posted by gfim (Graham Menhennitt) (Guest)
on 2012-11-22 21:57
(Received via mailing list)
Issue #7424 has been reported by gfim (Graham Menhennitt).

----------------------------------------
Bug #7424: an embedded Ruby interpreter doesn't get the full Ruby 
environment unless it calls ruby_process_options() (which is not 
documented)
https://bugs.ruby-lang.org/issues/7424

Author: gfim (Graham Menhennitt)
Status: Open
Priority: Normal
Assignee:
Category:
Target version:
ruby -v: ruby 1.9.3p327 (2012-11-10 revision 37606) [i686-linux]


The documented way to embed a Ruby interpreter is to call:

    RUBY_INIT_STACK;
    ruby_init();
    ruby_init_loadpath();

However, this leaves the Ruby environment incomplete. As an example, the 
following program:

#include <ruby.h>

int
main(int argc, char *argv[])
{
    RUBY_INIT_STACK;
    ruby_init();
    ruby_init_loadpath();

    rb_eval_string("p Mutex.new.methods");

    return 0;
}

prints:

[:locked?, :try_lock, :lock, :unlock, :sleep, :nil?, :===, :=~, :!~, 
:eql?, :hash, :<=>, :class, :singleton_class, :clone, :dup, 
:initialize_dup, :initialize_clone, :taint, :tainted?, :untaint, 
:untrust, :untrusted?, :trust, :freeze, :frozen?, :to_s, :inspect, 
:methods, :singleton_methods, :protected_methods, :private_methods, 
:public_methods, :instance_variables, :instance_variable_get, 
:instance_variable_set, :instance_variable_defined?, :instance_of?, 
:kind_of?, :is_a?, :tap, :send, :public_send, :respond_to?, 
:respond_to_missing?, :extend, :display, :method, :public_method, 
:define_singleton_method, :object_id, :to_enum, :enum_for,
:==, :equal?, :!, :!=, :instance_eval, :instance_exec, :__send__, 
:__id__]

Whereas running "ruby -e 'p Mutex.new.methods'" produces:

[:locked?, :try_lock, :lock, :unlock, :sleep, :synchronize, :nil?, :===, 
:=~, :!~, :eql?, :hash, :<=>, :class, :singleton_class, :clone, :dup, 
:initialize_dup, :initialize_clone, :taint, :tainted?, :untaint, 
:untrust, :untrusted?, :trust, :freeze, :frozen?, :to_s, :inspect, 
:methods, :singleton_methods, :protected_methods, :private_methods, 
:public_methods, :instance_variables, :instance_variable_get, 
:instance_variable_set, :instance_variable_defined?, :instance_of?, 
:kind_of?, :is_a?, :tap, :send, :public_send, :respond_to?, 
:respond_to_missing?, :extend, :display, :method, :public_method, 
:define_singleton_method, :object_id, :to_enum, :enum_for, :==, :equal?, 
:!, :!=, :instance_eval, :instance_exec, :__send__, :__id__]

Note that ":synchronize" is missing from the former. This is because 
ruby_init_prelude() has not been called - that's what adds synchronize() 
to Mutex.

A workwaround is to call ruby_process_options() as in the following:

#include <ruby.h>

int
main(int argc, char *argv[])
{
    RUBY_INIT_STACK;
    ruby_init();
    ruby_init_loadpath();
    static char* args[] = { "ruby", "/dev/null" };
    ruby_process_options(2, args);

    rb_eval_string("p Mutex.new.methods");

    return 0;
}

This seems very clumsy!

Some possible solutions are:
- call ruby_init_prelude() from ruby_init()
- change the linkage of ruby_init_prelude() to be non-static and have 
the Ruby embedded program call it explicitly (requires a documentation 
change).
Posted by mame (Yusuke Endoh) (Guest)
on 2012-11-24 09:33
(Received via mailing list)
Issue #7424 has been updated by mame (Yusuke Endoh).

Target version set to next minor


----------------------------------------
Feature #7424: an embedded Ruby interpreter doesn't get the full Ruby 
environment unless it calls ruby_process_options() (which is not 
documented)
https://bugs.ruby-lang.org/issues/7424#change-33799

Author: gfim (Graham Menhennitt)
Status: Assigned
Priority: Normal
Assignee: ko1 (Koichi Sasada)
Category:
Target version: next minor


The documented way to embed a Ruby interpreter is to call:

    RUBY_INIT_STACK;
    ruby_init();
    ruby_init_loadpath();

However, this leaves the Ruby environment incomplete. As an example, the 
following program:

#include <ruby.h>

int
main(int argc, char *argv[])
{
    RUBY_INIT_STACK;
    ruby_init();
    ruby_init_loadpath();

    rb_eval_string("p Mutex.new.methods");

    return 0;
}

prints:

[:locked?, :try_lock, :lock, :unlock, :sleep, :nil?, :===, :=~, :!~, 
:eql?, :hash, :<=>, :class, :singleton_class, :clone, :dup, 
:initialize_dup, :initialize_clone, :taint, :tainted?, :untaint, 
:untrust, :untrusted?, :trust, :freeze, :frozen?, :to_s, :inspect, 
:methods, :singleton_methods, :protected_methods, :private_methods, 
:public_methods, :instance_variables, :instance_variable_get, 
:instance_variable_set, :instance_variable_defined?, :instance_of?, 
:kind_of?, :is_a?, :tap, :send, :public_send, :respond_to?, 
:respond_to_missing?, :extend, :display, :method, :public_method, 
:define_singleton_method, :object_id, :to_enum, :enum_for,
:==, :equal?, :!, :!=, :instance_eval, :instance_exec, :__send__, 
:__id__]

Whereas running "ruby -e 'p Mutex.new.methods'" produces:

[:locked?, :try_lock, :lock, :unlock, :sleep, :synchronize, :nil?, :===, 
:=~, :!~, :eql?, :hash, :<=>, :class, :singleton_class, :clone, :dup, 
:initialize_dup, :initialize_clone, :taint, :tainted?, :untaint, 
:untrust, :untrusted?, :trust, :freeze, :frozen?, :to_s, :inspect, 
:methods, :singleton_methods, :protected_methods, :private_methods, 
:public_methods, :instance_variables, :instance_variable_get, 
:instance_variable_set, :instance_variable_defined?, :instance_of?, 
:kind_of?, :is_a?, :tap, :send, :public_send, :respond_to?, 
:respond_to_missing?, :extend, :display, :method, :public_method, 
:define_singleton_method, :object_id, :to_enum, :enum_for, :==, :equal?, 
:!, :!=, :instance_eval, :instance_exec, :__send__, :__id__]

Note that ":synchronize" is missing from the former. This is because 
ruby_init_prelude() has not been called - that's what adds synchronize() 
to Mutex.

A workwaround is to call ruby_process_options() as in the following:

#include <ruby.h>

int
main(int argc, char *argv[])
{
    RUBY_INIT_STACK;
    ruby_init();
    ruby_init_loadpath();
    static char* args[] = { "ruby", "/dev/null" };
    ruby_process_options(2, args);

    rb_eval_string("p Mutex.new.methods");

    return 0;
}

This seems very clumsy!

Some possible solutions are:
- call ruby_init_prelude() from ruby_init()
- change the linkage of ruby_init_prelude() to be non-static and have 
the Ruby embedded program call it explicitly (requires a documentation 
change).
Please log in before posting. Registration is free and takes only a minute.
Existing account (Switch to SSL-encrypted connection)
NEW: Do you have a Google/GoogleMail or Yahoo account? No registration required!
Log in with Google account | Log in with Yahoo account
No account? Register here.