Bug #4403

require command loads file twice when required symlink or file under directory which is symlink (symbolic link)

Added by rupert (Robert Pankowecki) over 1 year ago. Updated 11 months ago.

[ruby-core:35262]
Status:Rejected Start date:02/16/2011
Priority:Normal Due date:
Assignee:nahi (Hiroshi Nakamura) % Done:

0%

Category:core
Target version:1.9.3
ruby -v:ruby 1.9.2p136 (2010-12-25 revision 30365) [i686-linux]

Description

Consider this file structure:

~/test/symbolic  > tree
.
|-- a
|   `-- a.rb
|-- b -> a
|-- c.rb
`-- d.rb -> c.rb


Current behavior:

ruby-1.9.2-p136 :001 > require './c'
 => true 
ruby-1.9.2-p136 :002 > require './d'
./d.rb:1: warning: already initialized constant CON2
 => true 
ruby-1.9.2-p136 :003 > require './a/a'
 => true 
ruby-1.9.2-p136 :004 > require './b/a'
./b/a.rb:1: warning: already initialized constant CON
 => true 

Expected behavior:

ruby-1.9.2-p136 :001 > require './c'
 => true 
ruby-1.9.2-p136 :002 > require './d'
 => false
ruby-1.9.2-p136 :003 > require './a/a'
 => true 
ruby-1.9.2-p136 :004 > require './b/a'
 => false

This bug can be reproduced at Ruby 1.8.7, too.

History

Updated by wyhaines (Kirk Haines) over 1 year ago

On Wed, Feb 16, 2011 at 7:48 AM, Robert Pankowecki
<redmine@ruby-lang.org> wrote:
> Bug #4403: require command loads file twice when required symlink or file under directory which is symlink (symbolic link)
> http://redmine.ruby-lang.org/issues/show/4403
>
> Author: Robert Pankowecki
> Status: Open, Priority: Normal
> ruby -v: ruby 1.9.2p136 (2010-12-25 revision 30365) [i686-linux]
>
> Consider this file structure:
>
> ~/test/symbolic  > tree
> .
> |-- a
> |   `-- a.rb
> |-- b -> a
> |-- c.rb
> `-- d.rb -> c.rb
>
>
> Current behavior:
>
> ruby-1.9.2-p136 :001 > require './c'
>  => true
> ruby-1.9.2-p136 :002 > require './d'
> ./d.rb:1: warning: already initialized constant CON2
>  => true
> ruby-1.9.2-p136 :003 > require './a/a'
>  => true
> ruby-1.9.2-p136 :004 > require './b/a'
> ./b/a.rb:1: warning: already initialized constant CON
>  => true
>
> Expected behavior:
>
> ruby-1.9.2-p136 :001 > require './c'
>  => true
> ruby-1.9.2-p136 :002 > require './d'
>  => false
> ruby-1.9.2-p136 :003 > require './a/a'
>  => true
> ruby-1.9.2-p136 :004 > require './b/a'
>  => false
>
> This bug can be reproduced at Ruby 1.8.7, too.

The behavior that you are seeing is what is expected. Ruby is using
the path of the required file to differentiate between files which
have been required before, and those which have not been.

This has been well documented in the code and elsewhere for a long time.

Take a look in eval.c, searching for "rb_f_require", in a 1.8.x series
source code, and in the 1.9.x code, look in load.c. The
comment//documentation is identical except for the last sentence,
which details a single important difference:


Ruby 1.8.6:

[This first chunk is identical]

 *  Ruby tries to load the library named _string_, returning
 *  +true+ if successful. If the filename does not resolve to
 *  an absolute path, it will be searched for in the directories listed
 *  in <code>$:</code>. If the file has the extension ``.rb'', it is
 *  loaded as a source file; if the extension is ``.so'', ``.o'', or
 *  ``.dll'', or whatever the default shared library extension is on
 *  the current platform, Ruby loads the shared library as a Ruby
 *  extension. Otherwise, Ruby tries adding ``.rb'', ``.so'', and so on
 *  to the name. The name of the loaded feature is added to the array in
 *  <code>$"</code>. A feature will not be loaded if it's name already

[This last sentence is what is different]

 *  appears in <code>$"</code>. However, the file name is not converted
 *  to an absolute path, so that ``<code>require 'a';require
 *  './a'</code>'' will load <code>a.rb</code> twice.

Ruby 1.9.3 trunk, as of today:

[Just the part that is different.]

 * .... The file name is converted to an absolute
 *  path, so ``<code>require 'a'; require './a'</code>'' will not load
 *  <code>a.rb</code> twice.

In both cases, though, a link, which creates two different _absolute_
paths to the the same file, will allow it to get required twice. This
is expected.


Kirk Haines

Updated by nahi (Hiroshi Nakamura) 11 months ago

  • Status changed from Open to Assigned
  • Assignee set to nahi (Hiroshi Nakamura)
  • Target version set to 1.9.3

Updated by nahi (Hiroshi Nakamura) 11 months ago

  • Category set to core
  • Status changed from Assigned to Rejected
As Kirk said. 1.9 expands a path for required feature for double load detection but it does not follow symlink. I can understand that some user think it as a bug but following symlink should be handled at OS layer, not at Ruby language layer I think. I don't expect 'require "foo"' adds '/path/to/bar.rb' to $LOADED_FEATURES. I close this ticket as 'Not a Bug'. Please re-file a new issue for require+symlink as 'Feature' if you think it good to be added.

Also available in: Atom PDF