Strange bug : can someone explain this

ruby 1.9.3-p429

This happens on Windows, I do not know for other platforms. It seems
ruby can load files twice, by capitalizing file names.

For instance :

irb(main):001:0> require ‘set’
=> true # loaded
irb(main):002:0> require ‘set’
=> false # already loaded
irb(main):003:0> require ‘Set’
C:/Ruby193/lib/ruby/1.9.1/Set.rb:451: warning: already initialized
constant InspectKey
=> true # loaded again !!!
irb(main):004:0> require ‘Set’
=> false # twice ok but not more !

Note : there is no Set.rb file in the named directory !

A more spectacular case :

irb(main):001:0> require ‘tempfile’
=> true
irb(main):002:0> require ‘Tempfile’
TypeError: superclass mismatch for class Tempfile
from C:/Ruby193/lib/ruby/1.9.1/Tempfile.rb:81:in `<top
(required)>’

And again, there really is a ‘tempfile.rb’ in C:/Ruby193/lib/ruby/1.9.1,
but there is no ‘Tempfile.rb’ there.

_md

Michel D. [email protected] wrote:

=> false # already loaded
irb(main):003:0> require ‘Set’
C:/Ruby193/lib/ruby/1.9.1/Set.rb:451: warning: already initialized

Looks like you’re using a case-insensitive filesystem :<

Eric W. wrote in post #1119986:

Michel D. [email protected] wrote:

=> false # already loaded
irb(main):003:0> require ‘Set’
C:/Ruby193/lib/ruby/1.9.1/Set.rb:451: warning: already initialized

Looks like you’re using a case-insensitive filesystem :<

  1. Yes, Windows is case-insensitive.
  2. But ruby should not load twice the same file.

I guess ruby implementations on case-insensitive systems (Windows)
should add a protection. Specially when, like ‘tempfile’, loading twice
create an error. I was bitten by this very case and took quite a long
time to find out the reason : I had a - wrong but invisible to ruby -
“require ‘Tempfile’” in my code, and worked in an IDE (RubyMine) using
“require ‘tempfile’” internally.

_md

Michel D. [email protected] wrote:

I guess ruby implementations on case-insensitive systems (Windows)
should add a protection. Specially when, like ‘tempfile’, loading twice

It’s expensive, and hard to get right (consider various encodings, not
just ASCII).

Also, it’s possible to run case-insensitive FS on all OSes, not just
Windows; so everybody pays the price.

Also, not all case-insensitive/normalizing FSes behave the same way.
Some have slightly different rules when it comes to UTF-* than others.
They’re all horrible.

create an error. I was bitten by this very case and took quite a long
time to find out the reason : I had a - wrong but invisible to ruby -
“require ‘Tempfile’” in my code, and worked in an IDE (RubyMine) using
“require ‘tempfile’” internally.

Consider it a horrible practice to capitalize filename arguments and
stop doing that (and encourage others to do the same).

Eric W. wrote in post #1119996:

Consider it a horrible practice to capitalize filename arguments and
stop doing that (and encourage others to do the same).

The trouble is that it was not a practice, but just a typing error in a
list of requires in a file unchanged and unread for months. And this
error went unnoticed, because ruby did not complain.

I found it only when running a certain test in RubyMine in a certain
special case raised an error.

A (bad ?) solution would be for ‘require’ to give a warning when the
filename argument is capitalized. Why not ?
_md

Michel D. wrote in post #1120005:

A (bad ?) solution would be for ‘require’ to give a warning when the
filename argument is capitalized. Why not ?

Well, on some filesystems (such as the EXT family in Linux), filenames
are case-sensitive, so it is possible to create both tempfile.rb and
Tempfile.rb in the same directory, and load them independently of each
other. Whether or not there’s a legitimate use-case is another issue
altogether.

In a similar vein, if you’d run your script on a case-sensitive
filesystem (or in Linux) the error would have emerged immediately:
LoadError: cannot load such file – Tempfile

Maybe the Windows build of ruby could canonicalise filenames before
requiring them, but that would be a system-specific thing, not a part of
ruby as a whole. A similar thing would already have to be done on a VMS
system, for example, to convert ruby’s “a/b/c.rb” syntax to the
filesystem’s “[A.B]C.RB”

However the next most immediate issue I can imagine in that can of worms
is: how much normalisation should be done? Some filesystems are ASCII,
some support UTF-8, some use other standard or custom encodings. Now
that we’ve added a canonicalisation/normalisation on Windows/DOS
filesystems, do we also add a conversion to/from various encodings for
each system and its filesystem’s quirks? On a fictional UTF-8-friendly
filesystem I just invented, does the file “flickvän.rb”
(\xef\xac\x82\x69\x63\x6b\x76\xc3\xa4\x6e\x2e\x72\x62) correspond with
“flickvän.rb” (\x66\x6c\x69\x63\x6b\x76\xc3\xa4\x6e\x2e\x72\x62) or
“flickvän.rb” (\xef\xac\x82\x69\x63\x6b\x76\x61\xcc\x88\x6e\x2e\x72\x62)?
Is it ruby’s job to know this, or enforce it?

On Aug 29, 2013, at 3:43 PM, Eric W. [email protected] wrote:

Also, it’s possible to run case-insensitive FS on all OSes, not just
Windows; so everybody pays the price.

I just found this to be the case on my new mbp, that defaults to
HFS-Insenstive. This was driving me bonkers, since bash completion is
not tuned for it , either.