Issue #9906 has been updated by Tomoyuki Chikanaga.

Status changed from Open to Rejected

Hello, Martin.

It is not a bug.

At first, please take a look at the script belows.

Script:

    $LOAD_PATH << "."
    File.unlink "dbm.rb" if File.exist?("dbm.rb")
    p require "dbm"
    
    open("dbm.rb", "w") do |f|
      f.puts(<<-EOF)
        p "local dbm.rb is loaded"
      EOF
    end
    
    p require "dbm"

Result:

    true
    "local dbm.rb is loaded"
    true

Kernel#require search a script/extention library file in $LOAD_PATH directories in order.
Even though the feature was already loaded, Kernel#require search $LOAD_PATH for a new file which have higher priority.
In your example, require "digest/md5" search under site_ruby, vendor_ruby etc.

----------------------------------------
Bug #9906: duplicated require of '.so' files?
https://bugs.ruby-lang.org/issues/9906#change-47798

* Author: Martin Sarsale
* Status: Rejected
* Priority: Normal
* Assignee: 
* Category: core
* Target version: 
* ruby -v: ruby 2.1.0p0 (2013-12-25 revision 44422) [i686-linux]
* Backport: 2.0.0: UNKNOWN, 2.1: UNKNOWN
----------------------------------------
Dear all,

We are trying to get rid of autoload;
We could require everything in the first line of the file but instead we
prefer to require only what we need, when we need it.

So, instead of

 require "digest/md5"
 def foo(n)
  Digest::MD5.hexdigest(n)
 end

we would like to do:

 def foo(n)
  require "digest/md5"
  Digest::MD5.hexdigest(n)
 end


The problem we've found, is that duplicate `require(name)`, satisfied by
".rb" files are only executed once; but when file loaded by
require(name) is a '.so', next requires with the same name will be
executed again and again.

Example:

$ cat require-rb.rb

def foo(n)
  require "set"
  Set.new([n])
end
1000.times{|n|
  puts foo(n)
}

$ strace -e trace=file -o require-rb.log ruby require-rb.rb
$ grep -c -E 'open.*/set'  require-rb.log
8


$ cat require-so.rb

def foo(n)
  require "digest/md5"
  Digest::MD5.hexdigest(n.to_s)
end
1000.times{|n|
  puts foo(n)
}

$ strace -e trace=file -o require-so.log ruby require-so.rb
$ grep -c -E 'open.*/md5'  require-so.log
16001


Is this a bug or a feature?



-- 
https://bugs.ruby-lang.org/