[PATCH] Extension libraries take precedence in checks of later Kernel.#require calls for features without file extensions
Extension libraries take precedence in checks of later
Kernel.#require calls for features without file extensions. That behavior is inconsistent with the first call, and can cause problems.
For instance, feature
openssl.so, but it assumes
openssl.rb will always be loaded when it gets required. That assumption works for the first call of
Kernel.#require, but for the later calls,
openssl.so is being required and checks if the file is valid for the requirement.
Usually that is not so problematic since it just check if
openssl.so, which is already required by
openssl.rb, is required or not. However, if there is a new alternative
$:, the file will be loaded and conflict with the feature already loaded.
The below is a code example.
p $:.include? '/usr/lib/ruby/2.4.0' # true p $:.include? '/home/aki/mastodon/vendor/bundle/ruby/2.4.0/gems/openssl-2.0.5/lib' # false p $".include? '/usr/lib/ruby/2.4.0/openssl/openssl.rb' # false p $".include? '/home/aki/mastodon/vendor/bundle/ruby/2.4.0/gems/openssl-2.0.5/lib/openssl.rb' # false require 'openssl' p $".include? '/usr/lib/ruby/2.4.0/openssl/openssl.rb' # true p $".include? '/home/aki/mastodon/vendor/bundle/ruby/2.4.0/gems/openssl-2.0.5/lib/openssl.rb' # false $:.unshift '/home/aki/mastodon/vendor/bundle/ruby/2.4.0/gems/openssl-2.0.5/lib' require 'openssl' p $".include? '/home/aki/mastodon/vendor/bundle/ruby/2.4.0/gems/openssl-2.0.5/lib/openssl.rb' # true (unexpected)
Updated by jeremyevans0 (Jeremy Evans) about 2 years ago
- Status changed from Open to Closed
This patch appears to change a general behavior of
require even when extension libraries are not involved. For example, it changes the behavior of this code:
Dir.mkdir('a') Dir.mkdir('b') File.write('a/c.rb', '$a = 1') File.write('b/c.rb', '$a = 2') $:.unshift('a') require 'c' p $a $:.unshift('b') require 'c' p $a # Before: 2 # With Patch: 1
I don't think Ruby's current behavior here is a bug.
require will not load the same file path a second time, but it will load a different file path for the same argument if there has been a change to the load path. The documentation for
require describes this behavior:
A file will not be loaded again if its path already appears in $" (saying nothing about the argument to
require). As the current behavior does not appear to be a bug, I'm going to close this.