Gem install wrong number of arguments (given 1, expected 0)

最后都变了- 提交于 2019-12-20 01:11:25

问题


When I run bundle, I get the following:

The `bundle' command exists in these Ruby versions: 2.1.8 2.4.2 jruby-9.1.15.0

My project uses Ruby-2.5.1, so I'm trying to update my bundler using gem install bundler, but I get the following error:

ERROR: While executing gem ... (ArgumentError) wrong number of arguments (given 1, expected 0)

Using --backtrace

/Users/spencerbailey/.rbenv/versions/2.5.1/lib/ruby/site_ruby/2.5.0/rubygems/core_ext/kernel_require.rb:47:in `require'
/Users/spencerbailey/.rbenv/versions/2.5.1/lib/ruby/site_ruby/2.5.0/rubygems/installer.rb:162:in `initialize'
/Users/spencerbailey/.rbenv/versions/2.5.1/lib/ruby/site_ruby/2.5.0/rubygems/installer.rb:104:in `new'
/Users/spencerbailey/.rbenv/versions/2.5.1/lib/ruby/site_ruby/2.5.0/rubygems/installer.rb:104:in `at'
/Users/spencerbailey/.rbenv/versions/2.5.1/lib/ruby/site_ruby/2.5.0/rubygems/resolver/specification.rb:93:in `install'
/Users/spencerbailey/.rbenv/versions/2.5.1/lib/ruby/site_ruby/2.5.0/rubygems/request_set.rb:166:in `block in install'
/Users/spencerbailey/.rbenv/versions/2.5.1/lib/ruby/site_ruby/2.5.0/rubygems/request_set.rb:156:in `each'
/Users/spencerbailey/.rbenv/versions/2.5.1/lib/ruby/site_ruby/2.5.0/rubygems/request_set.rb:156:in `install'
/Users/spencerbailey/.rbenv/versions/2.5.1/lib/ruby/site_ruby/2.5.0/rubygems/commands/install_command.rb:251:in `install_gem'
/Users/spencerbailey/.rbenv/versions/2.5.1/lib/ruby/site_ruby/2.5.0/rubygems/commands/install_command.rb:301:in `block in install_gems'
/Users/spencerbailey/.rbenv/versions/2.5.1/lib/ruby/site_ruby/2.5.0/rubygems/commands/install_command.rb:297:in `each'
/Users/spencerbailey/.rbenv/versions/2.5.1/lib/ruby/site_ruby/2.5.0/rubygems/commands/install_command.rb:297:in `install_gems'
/Users/spencerbailey/.rbenv/versions/2.5.1/lib/ruby/site_ruby/2.5.0/rubygems/commands/install_command.rb:204:in `execute'
/Users/spencerbailey/.rbenv/versions/2.5.1/lib/ruby/site_ruby/2.5.0/rubygems/command.rb:310:in `invoke_with_build_args'
/Users/spencerbailey/.rbenv/versions/2.5.1/lib/ruby/site_ruby/2.5.0/rubygems/command_manager.rb:169:in `process_args'
/Users/spencerbailey/.rbenv/versions/2.5.1/lib/ruby/site_ruby/2.5.0/rubygems/command_manager.rb:139:in `run'
/Users/spencerbailey/.rbenv/versions/2.5.1/lib/ruby/site_ruby/2.5.0/rubygems/gem_runner.rb:55:in `run'
/Users/spencerbailey/.rbenv/versions/2.5.1/bin/gem:21:in `<main>'

Extra information:

  • Rails 5.1.2
  • Ruby-2.5.1
  • macOS High Sierra Version 10.13.4

回答1:


This was happening on my system, so I dug into it for a while. It appears to be an incompatibility between Ruby 2.5 and RubyGems < 2.6.10.

Short answer

If you want to install Ruby 2.5, make sure you have RubyGems >= 2.6.10. You may be able to explicitly specify which version of RubyGems to use (for example, I called rvm rubygems 2.7.7) or it may work to just update to a newer version of RVM/rbenv/etc.

Longer explanation

As shown in the backtrace in the question, the error occurs when calling require. This is a version of require that RubyGems has written to replace the definition that comes with Ruby. In RubyGems before 2.6.10, this part of the code looks something like:

spec = Gem.find_unresolved_default_spec(path)
if spec
  Gem.remove_unresolved_default_spec(spec)
  gem(spec.name)
end

(source)

The error occurs when calling gem(spec.name), but why?

It ends up having to do with a quirk of Ruby. Even though require seems kind of like a built-in keyword, it's actually a method in the Kernel module. That module is included in Object, so the method can be called from any object that descends from Object (including the "main" object at the top level of a script/console). But in the end it's still a method on whatever object you call it from, so any method calls within require that don't have an explicit receiver are called on that same object.

Normal inheritance rules apply, so if your object doesn't have an explicit gem method, the one defined in Kernel by RubyGems will be called, which is great. But if your object does have its own gem method, that'll be called instead, which is unlikely to work. In this case, require 'fileutils' is called from within the initializer for Gem::Installer (https://github.com/rubygems/rubygems/blob/v2.6.9/lib/rubygems/installer.rb#L162). The Gem::Installer class has its own gem method with zero parameters, created by attr_reader :gem. The require code tries to call it with one parameter, and there we have our error.

(This issue was resolved in RubyGems 2.6.10 by changing the gem call to Kernel.send(:gem, spec.name) in https://github.com/rubygems/rubygems/pull/1822. This was prompted by somewhat similar difficulties in the Bundler library, which also had an object defining its own gem method.)

The last question is why this occurred in Ruby 2.5 but not before. It turns out that this particular call to gem only occurs when trying to require a "default" gem. In versions of Ruby before 2.5, "fileutils" has not been a default gem, so those versions have managed to avoid this particular issue, even with older versions of RubyGems. It's only with Ruby 2.5 making "fileutils" a default gem that this odd issue has cropped up.




回答2:


(Posted on behalf of the question author).

I solved it by reinstalling Rbenv and then using rbenv rehash.



来源:https://stackoverflow.com/questions/51139114/gem-install-wrong-number-of-arguments-given-1-expected-0

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!