psych.so ファイルが適切な場所に置かれていない。
問題回避方法
私のケースでは:
cp /usr/local/share/ruby/gems/2.0/gems/psych-2.0.13/lib/psych.so \ /usr/share/ruby/vendor_ruby/2.0/
詳細
path2class メソッドは psych_to_ruby.c 内で定義され、rb_define_private_method() により Psych::ClassLoader クラスのプライベートメソッドとして登録される。下記はそのコード。Init_psych_to_ruby() 関数の最後の行に注目。
static VALUE path2class(VALUE self, VALUE path) { #ifdef HAVE_RUBY_ENCODING_H return rb_path_to_class(path); #else return rb_path2class(StringValuePtr(path)); #endif } void Init_psych_to_ruby(void) { VALUE psych = rb_define_module("Psych"); VALUE class_loader = rb_define_class_under(psych, "ClassLoader", rb_cObject); VALUE visitors = rb_define_module_under(psych, "Visitors"); VALUE visitor = rb_define_class_under(visitors, "Visitor", rb_cObject); cPsychVisitorsToRuby = rb_define_class_under(visitors, "ToRuby", visitor); rb_define_private_method(cPsychVisitorsToRuby, "build_exception", build_exception, 2); rb_define_private_method(class_loader, "path2class", path2class, 1); }
Init_psych_to_ruby() 関数は、psych.c で定義されている Init_psych() 関数から呼ばれている。
void Init_psych(void) { mPsych = rb_define_module("Psych"); rb_define_singleton_method(mPsych, "libyaml_version", libyaml_version, 0); Init_psych_parser(); Init_psych_emitter(); Init_psych_to_ruby(); Init_psych_yaml_tree(); }
Ruby は、ライブラリの共有ライブラリ (.so ファイル) をロードしたあと、「Init_ライブラリ名()」関数を呼ぶ。そのため、Psych の場合、psych.so が見つかりロードされれば、Init_psych() 関数が呼ばれ、それから Init_psych_to_ruby() が呼ばれ、結果 path2class メソッドが登録されることになる。しかし、もしも psych.so が存在しなければ、path2class メソッドは登録されず、"undefined method `path2class'" というエラーメッセージを見ることになる。
おそらく、Ruby もしくは Psych のパッケージングプロセスに何らかの問題があると思われる。
参照
- GitHub: Psych Issue 182, psych won't install on Ruby 2.0.0-p353, libyaml-0.1.4, on OSX 10.8.5
- StackOverflow: Clean install OSX 10.9.1 returns "undefined method `path2class'" when trying to install gems