Blog

Unknown encoding in ruby 1.9.1-p429 (4 comment)

Added by Christoph Kappel about 7 years ago

Updating Ruby is usually a task that breaks many things, therefore I avoid it if possible. Being archuser, the maintainer of the Ruby decides when I need to face new problems.

This time they just added filesystem encoding stuff in p429:

Error loading gem paths on load path in gem_prelude
unknown encoding name - filesystem
<internal:gem_prelude>:69:in `find'
<internal:gem_prelude>:69:in `set_home'
<internal:gem_prelude>:38:in `dir'
<internal:gem_prelude>:76:in `set_paths'
<internal:gem_prelude>:47:in `path'
<internal:gem_prelude>:286:in `push_all_highest_version_gems_on_load_path'
<internal:gem_prelude>:355:in `<compiled>'

There exists still now sane way to init the gem path of Ruby so we can start with our hack from Setup gems load path in embedded ruby and add the required encoding stuff. This problem is known in the ruby redmine and the changesets to this issue give at least some hints what need to be done:

Numbers: on /off 1 #include <ruby/encoding.h>
 2 
 3 VALUE encoding = Qnil;
 4 
 5 void Init_prelude(void);
 6 
 7 RUBY_INIT_STACK;
 8 ruby_init();
 9 ruby_init_loadpath();
10 ruby_script("subtle");
11 
12 /* Get encoding from file system */
13 encoding = rb_enc_from_encoding(rb_filesystem_encoding());
14 
15 /* Set internal and external encoding */
16 rb_enc_set_default_internal(encoding);
17 rb_enc_set_default_external(encoding);
18 
19 /* FIXME: Fake ruby_init_gems(Qtrue) */
20 rb_define_module("Gem");
21 Init_prelude();

Setup gems load path in embedded ruby (1 comment)

Added by Christoph Kappel over 7 years ago

Ruby lacks a way to proper init the load path for gems without using stuff like ruby_options(), which will make things even worse. Generally this is, because Ruby wasn't developed to be embedded in the first place, that also explains the lack of docs about this topic.

Reading through the code these lines here are exactly what we are looking for:

Numbers: on /off 1 /* ruby.c:1055: */
 2 void Init_prelude(void);
 3 
 4 static void                                            
 5 ruby_init_gems(int enable)                                
 6 {
 7   if (enable) rb_define_module("Gem");                                   
 8   Init_prelude();                                             
 9 }

Looks good, but ruby_init_gems() is static and thus not accessable by third party like us. The workaround is to mimic the function in our code, this includes the forward declaration of Init_prelude() or our compiler will complain about it.

In subtle I use the following to init the vm:

Numbers: on /off 1 void Init_prelude(void);
 2 
 3 RUBY_INIT_STACK;
 4 ruby_init();
 5 ruby_init_loadpath();
 6 ruby_script("subtle");
 7 
 8 /* FIXME: Fake ruby_init_gems(Qtrue) */
 9 rb_define_module("Gem");
10 Init_prelude();

If you insist to know what Init_prelude() really does have a look at the miniprelude.c file of the Ruby tarball.

Also available in: Atom RSS