Clean install OSX 10.9.1 returns “undefined method

2019-03-23 18:23发布

问题:

I just installed a clean Mavericks installation with Homebrew and RVM. Both brew doctor and rvm requirements return "all good", however, when I run bundle install in my project dir most of my gems install fine, but a handful fail to install with the same following error:

Bundler::GemspecError: Could not read gem at /Users/NK/.rvm/gems/ruby-2.0.0-p353/cache/eventmachine-1.0.3.gem. It may be corrupted.
An error occurred while installing eventmachine (1.0.3), and Bundler cannot continue.
Make sure that `gem install eventmachine -v '1.0.3'` succeeds before bundling.

Then, if I try again with gem install eventmachine -v '1.0.3' I get:

ERROR:  Error installing eventmachine:
    invalid gem: package is corrupt, exception while verifying: undefined method `path2class' for #<Psych::ClassLoader:0x000001018f7990> (NoMethodError) in /Users/NK/.rvm/gems/ruby-2.0.0-p353/cache/eventmachine-1.0.3.gem

I tried to implode RVM and reinstall, but nothing helps.

Other people seem to have the same problem, but no one seems to have fund the answer yet:

  • http://pastebin.com/LV53GdR2
  • Install Rails Error "invalid gem: package is corrupt"
  • Error install rubyracer with error "invalid gem: package is corrupt"

EDIT

See those two as well:

  • https://github.com/tenderlove/psych/issues/182
  • https://github.com/wayneeseguin/rvm/issues/2620

回答1:

It turns out that this is a bug in an older version of psych, but it can't be solved, as long as you installed ruby with RVMs statically linked gems. So basically the problem is related to RVMs statically linked gems. Installing rubies with the --disable-binary solves the problem:

rvm install 2.0.0-p353 --disable-binary

Or reinstall with:

rvm reinstall 2.0.0-p353 --disable-binary


回答2:

I had the very same error and looked into the psych gem

$ gem list --local | grep psych
psych (2.0.4, 2.0.0)

as version 2.0.4 was recently installed I removed it, keeping only version 2.0.0

$ gem uninstall psych -v '2.0.4'
Successfully uninstalled psych-2.0.4

After that, everything worked fine again!



回答3:

Immediate Cause

psych.so is not located at the proper location.

Solution/Workaround

In my case,

cp /usr/local/share/ruby/gems/2.0/gems/psych-2.0.13/lib/psych.so \
   /usr/share/ruby/vendor_ruby/2.0/


Details

path2class method is defined in psych_to_ruby.c and registered into Psych::ClassLoader class as a private method by rb_define_private_method(). The following is the code. Take a look at the last line of Init_psych_to_ruby() function.

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() is called from Init_psych() function, which is defined in psych.c.

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 calls Init_{library}() function after it loads the library's shared library (.so file). So, in the case of psych, if psych.so is found and loaded, Init_psych() function is called and in turn Init_psych_to_ruby() is called, and finally path2class is registered. However, if psych.so does not exist, path2class is never registered and you will see the error message "undefined method `path2class'".

Probably, there is something wrong in the packaging process of either psych or Ruby.



回答4:

I was having the same problem and remembered that XCode had been updated recently. I was reminded of this because some Terminal output claimed that the developer tools were not installed and suggested running the following:

$ xcode-select --install

It still wasn't working so I used rvm to install the latest 2.1 version of Ruby, created a new gemset, pointed my app to use that gemset and ran $ bundle install. It now works.



回答5:

For me this turned out to be a permissions issue. I fixed it by resetting my permissions on my ~/.rvm folder. Mac OS X 10.9.3.

First, find your system username:

ls -lA ~ | head

Produces:

-rw-r--r--@  1 nperry  staff   43012 Jul  1 13:25 .DS_Store
drwx------  63 nperry  staff    2142 Jul  1 13:40 .Trash
...

My username is nperry and my group is staff. Change the following lines to match your user and group.

sudo chown -R nperry:staff  ~/.rvm
sudo chmod -R ug+rw ~/.rvm

And no more errors.



回答6:

This is not a particularly insightful answer, but in my case the problem went away by switching to ruby-2.1.2 (p95, incidentally) via rvm.

I was going to upgrade anyway...