Project

General

Profile

Actions

Bug #15500

closed

Behavior of require method in 2.5 is different from 2.4 and 2.6

Added by mrkn (Kenta Murata) almost 6 years ago. Updated over 5 years ago.

Status:
Closed
Target version:
-
ruby -v:
ruby 2.5.3p105 (2018-10-18 revision 65156) [x86_64-darwin18]
[ruby-core:90867]

Description

On Ruby 2.5, require 'bigdecimal' does not load bigdecimal.so in gem-installed version of bigdecimal without specifying the version by gem method.
You can examine this phenomenon by the following code.

require 'bigdecimal'
p $LOADED_FEATURES.grep(/bigdecimal/).first

After installing bigdecimal-1.4.2 by gem install bigdecimal command, this code (saved as t.rb) show the following results:

On Ruby 2.4.5

$ ruby-2.4.5 -v t.rb
ruby 2.4.5p335 (2018-10-18 revision 65137) [x86_64-darwin18]
"/Users/mrkn/.rbenv/versions/2.4.5/lib/ruby/gems/2.4.0/gems/bigdecimal-1.4.2/lib/bigdecimal.bundle"

On Ruby 2.5.3:

$ ruby-2.5.3 -v t.rb
ruby 2.5.3p105 (2018-10-18 revision 65156) [x86_64-darwin18]
"/Users/mrkn/.rbenv/versions/2.5.3/lib/ruby/2.5.0/x86_64-darwin18/bigdecimal.bundle"

On Ruby 2.6.0:

$ ruby-2.6.0 -v t.rb
ruby 2.6.0p0 (2018-12-25 revision 66547) [x86_64-darwin18]
"/Users/mrkn/.rbenv/versions/2.6.0/lib/ruby/gems/2.6.0/gems/bigdecimal-1.4.2/lib/bigdecimal.bundle"

On Ruby 2.5.3, with gem 'bigdecimal', '1.4.2', the correct file can be loaded.

$ ( echo "gem 'bigdecimal', '1.4.2'"; cat t.rb ) | ruby-2.5.3 -v -
ruby 2.5.3p105 (2018-10-18 revision 65156) [x86_64-darwin18]
"/Users/mrkn/.rbenv/versions/2.5.3/lib/ruby/gems/2.5.0/gems/bigdecimal-1.4.2/lib/bigdecimal.bundle"

Related issues 3 (0 open3 closed)

Related to Ruby master - Misc #15486: Default gems README.mdFeedbackhsbt (Hiroshi SHIBATA)Actions
Related to Ruby master - Bug #15545: Backport r58403Closednagachika (Tomoyuki Chikanaga)Actions
Related to Ruby master - Bug #15469: Ruby2.6 included `bundler` does not handle specified `csv` gem.Closedhsbt (Hiroshi SHIBATA)Actions
Actions #1

Updated by mrkn (Kenta Murata) almost 6 years ago

  • Description updated (diff)
Actions #2

Updated by marcandre (Marc-Andre Lafortune) almost 6 years ago

Updated by marcandre (Marc-Andre Lafortune) almost 6 years ago

I was expecting the behavior in 2.5. That's what is correct, right?

I tested with matrix gem, and 2.4 behaves like 2.5, which is to say it loads the gem only if gem 'matrix' is called. Note that 2.4 didn't ship with default matrix gem (it was std lib), but it did ship with defaut bigdecimal gem.

I also realized that it's not possible to load the 0.1.0 matrix gem in 2.6.0 because it shipped with that version of the local gem. That in itself is a problem, as the public gem matrix v0.1.0 is actually older than the local gem that has shipped with Ruby 2.6.0. I will release v1.0.0 to avoid this issue, and I will have to be careful when mirroring the gem.

Updated by mrkn (Kenta Murata) almost 6 years ago

I think the behavior of 2.5 can be thought of a bug because the behavior for .so file isn't consistent with one for .rb file.
You can see the inconsistency in the results below.

$ ruby -rbigdecimal/util -ve 'p $LOADED_FEATURES.grep(/bigdecimal/)'
ruby 2.5.3p105 (2018-10-18 revision 65156) [x86_64-linux]
["/usr/local/lib/ruby/gems/2.5.0/gems/bigdecimal-1.4.2/lib/bigdecimal.so", "/usr/local/lib/ruby/gems/2.5.0/gems/bigdecimal-1.4.2/lib/bigdecimal.rb", "/usr/local/lib/ruby/gems/2.5.0/gems/bigdecimal-1.4.2/lib/bigdecimal/util.so", "/usr/local/lib/ruby/gems/2.5.0/gems/bigdecimal-1.4.2/lib/bigdecimal/util.rb"]

In this case, bigdecimal/util is required, and the gem-installed version of bigdecimal/util.rb is loaded.
You can see the gem-installed version of bigdecimal.so is also loaded.

The behavior is changed when bigdecimal is required before bigdecimal/util.

$ ruby -rbigdecimal -rbigdecimal/util -ve 'p $LOADED_FEATURES.grep(/bigdecimal/)'
ruby 2.5.3p105 (2018-10-18 revision 65156) [x86_64-linux]
/usr/local/lib/ruby/gems/2.5.0/gems/bigdecimal-1.4.2/lib/bigdecimal.rb:7: warning: method redefined; discarding old new
Traceback (most recent call last):
	5: from /usr/local/lib/ruby/site_ruby/2.5.0/rubygems/core_ext/kernel_require.rb:54:in `require'
	4: from /usr/local/lib/ruby/site_ruby/2.5.0/rubygems/core_ext/kernel_require.rb:54:in `require'
	3: from /usr/local/lib/ruby/gems/2.5.0/gems/bigdecimal-1.4.2/lib/bigdecimal/util.rb:9:in `<top (required)>'
	2: from /usr/local/lib/ruby/site_ruby/2.5.0/rubygems/core_ext/kernel_require.rb:34:in `require'
	1: from /usr/local/lib/ruby/site_ruby/2.5.0/rubygems/core_ext/kernel_require.rb:130:in `rescue in require'
/usr/local/lib/ruby/site_ruby/2.5.0/rubygems/core_ext/kernel_require.rb:130:in `require': /usr/local/lib/ruby/gems/2.5.0/gems/bigdecimal-1.4.2/lib/bigdecimal/util.so: undefined symbol: rmpd_util_str_to_d - /usr/local/lib/ruby/gems/2.5.0/gems/bigdecimal-1.4.2/lib/bigdecimal/util.so (LoadError)

In this case, LoadError is occurred by the symbol resolution failure of bigdecimal/util.so. This file is newly introduced since bigdecimal-1.4.0.
Although bigdecimal.so in bigdecimal-1.4.2 has rmpd_util_str_to_d, it isn't loaded because the default-gem version of bigdecimal.so is loaded by -rbigdecimal option.

The difference between the default-gem and gem-installed versions is whether bigdecimal.rb exists. Although I've not investigated the implementation of Ruby 2.5's require` method yet, I consider that Ruby 2.5 won't search in the gem-installed version if there is .so file but there isn't .rb file.

Updated by hsbt (Hiroshi SHIBATA) almost 6 years ago

  • Status changed from Open to Assigned
  • Assignee set to hsbt (Hiroshi SHIBATA)

Updated by hsbt (Hiroshi SHIBATA) almost 6 years ago

I could reproduce them. But I also reproduce it with Ruby 2.5.3 with RubyGems 2.6.14.3 bundled with Ruby 2.4.

~ > ruby -v
ruby 2.5.3p105 (2018-10-18 revision 65156) [x86_64-darwin18]
~ > gem -v
2.6.14.3
~ > gem list bigdecimal

*** LOCAL GEMS ***

bigdecimal (1.4.3, default: 1.3.4)
~ > ruby -e "require 'bigdecimal'; p \$LOADED_FEATURES.grep(/bigdecimal/).first"
"/Users/hsbt/.rbenv/versions/2.5.3/lib/ruby/2.5.0/x86_64-darwin18/bigdecimal.bundle"

It seems this issue produced by Ruby core without RubyGems maybe.

Actions #7

Updated by mrkn (Kenta Murata) almost 6 years ago

Actions #8

Updated by hsbt (Hiroshi SHIBATA) almost 6 years ago

  • Status changed from Assigned to Closed

Applied in changeset trunk|r66867.


Revert r58345 and r58371.

These changes break the behavior of default gems. Bug #13428 says
r58345 is reasonable because gemspec file is installed by to_ruby_for_cache
method. But I revert to_ruby_for_cache in rbinstall.rb at r58403.
There is no reason that we apply r58345 now.

But I'm not sure about gemspec of default gems affects standalone gems.
I'm going to investigate it on rubygems/rubygems.

[Bug #15500][ruby-core:90867]

Updated by hsbt (Hiroshi SHIBATA) almost 6 years ago

@mrkn (Kenta Murata)

Can you try with Ruby 2.5 applied r66867?

Actions #10

Updated by hsbt (Hiroshi SHIBATA) almost 6 years ago

  • Backport changed from 2.4: UNKNOWN, 2.5: UNKNOWN, 2.6: UNKNOWN to 2.4: DONTNEED, 2.5: REQUIRED, 2.6: REQUIRED

Updated by naruse (Yui NARUSE) almost 6 years ago

  • Backport changed from 2.4: DONTNEED, 2.5: REQUIRED, 2.6: REQUIRED to 2.4: DONTNEED, 2.5: REQUIRED, 2.6: DONE

ruby_2_6 r66913 merged revision(s) 66867.

Updated by mrkn (Kenta Murata) almost 6 years ago

@hsbt (Hiroshi SHIBATA)
I've confirmed that Ruby 2.5 with r66867 loads bigdecimal installed by gem, correctly.

Actions #13

Updated by hsbt (Hiroshi SHIBATA) almost 6 years ago

  • Related to Bug #15469: Ruby2.6 included `bundler` does not handle specified `csv` gem. added

Updated by nagachika (Tomoyuki Chikanaga) over 5 years ago

  • Backport changed from 2.4: DONTNEED, 2.5: REQUIRED, 2.6: DONE to 2.4: DONTNEED, 2.5: DONE, 2.6: DONE

ruby_2_5 r67013 merged revision(s) 66867.

Actions

Also available in: Atom PDF

Like0
Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0