david% irb
irb(main):001:0> require 'Singleton’
irb(main):002:0> class Something
irb(main):003:1> include Singleton
irb(main):004:1> end
irb(main):005:0> require ‘log4r’
/usr/local/lib/ruby/1.8/singleton.rb:119: warning: already initialized
constant FirstInstanceCall
NameError: undefined method extend_object' forSingleton’
from /usr/local/lib/ruby/1.8/singleton.rb:161:in undef_method' from /usr/local/lib/ruby/1.8/singleton.rb:161 from /usr/local/lib/ruby/site_ruby/1.8/log4r/repository.rb:4:inrequire’
from /usr/local/lib/ruby/site_ruby/1.8/log4r/repository.rb:4
from
/usr/local/lib/ruby/site_ruby/1.8/log4r/outputter/
outputterfactory.rb:5:in require' from /usr/local/lib/ruby/site_ruby/1.8/log4r/outputter/outputterfactory.rb:5 from /usr/local/lib/ruby/site_ruby/1.8/log4r/outputter/outputter.rb:10:inrequire’
from
/usr/local/lib/ruby/site_ruby/1.8/log4r/outputter/outputter.rb:10
from
/usr/local/lib/ruby/site_ruby/1.8/log4r/outputter/iooutputter.rb:2:in require' from /usr/local/lib/ruby/site_ruby/1.8/log4r/outputter/iooutputter.rb:2 from /usr/local/lib/ruby/site_ruby/1.8/log4r/outputter/fileoutputter.rb:4:inrequire’
from
/usr/local/lib/ruby/site_ruby/1.8/log4r/outputter/fileoutputter.rb:4
from /usr/local/lib/ruby/site_ruby/1.8/log4r.rb:8:in require' from /usr/local/lib/ruby/site_ruby/1.8/log4r.rb:8 from (irb):5:inrequire’
from (irb):5
from
/usr/local/lib/ruby/site_ruby/1.8/log4r/outputter/
outputter.rb:118irb(main):006:0>
It doens’t do this unless I make another Singleton-class first. Any got
a clue?
david% irb
irb(main):001:0> require ‘Singleton’
irb(main):002:0> class Something
irb(main):003:1> include Singleton
irb(main):004:1> end
irb(main):005:0> require ‘log4r’
/usr/local/lib/ruby/1.8/singleton.rb:119: warning: already initialized
constant FirstInstanceCall
NameError: undefined method extend_object' for Singleton’
On windows you will get the same error message. However, if you
write
···
require ‘singleton’
class A
include Singleton
end
require ‘log4r’
you’ll be fine. My guess is that ruby thinks'' that Singleton.rb"
and singleton.rb" (in my case installed in E:/Ruby/lib/ruby/1.8) are different files - however in the windows world or on a Macs HFS+ file-system Singleton.rb" and ``singleton.rb’’ refer to the
same file.
This difference results in unnecessary reload of ``singleton.rb’’
which in turn triggers the NameError of Ruby trying to undefine
an already undefined method (extend_object).
I suggest that you consistently use the lower case version require
‘singleton’. Alternatively change the line
/usr/local/lib/ruby/1.8/singleton.rb:161:in undef_method': undefined method extend_object’ for Singleton' (NameError) from /usr/local/lib/ruby/1.8/singleton.rb:161 from /usr/local/lib/ruby/1.8/auto-reload.rb:77:in load’
from /usr/local/lib/ruby/1.8/auto-reload.rb:77:in require' from /usr/local/lib/ruby/site_ruby/1.8/log4r/repository.rb:4 from /usr/local/lib/ruby/1.8/auto-reload.rb:77:in load’
from /usr/local/lib/ruby/1.8/auto-reload.rb:77:in require' from /usr/local/lib/ruby/site_ruby/1.8/log4r/outputter/outputterfactory.rb:5 from /usr/local/lib/ruby/1.8/auto-reload.rb:77:in load’
… 12 levels…
from /usr/local/lib/ruby/1.8/auto-reload.rb:77:in require' from /Users/david/Sites/extranet/log4r.rbx:1 from /usr/local/lib/ruby/1.8/apache/ruby-run.rb:53:in load’
from /usr/local/lib/ruby/1.8/apache/ruby-run.rb:53:in `handler’
The contents of log4r.rbx works fine if used in IRB, but not under
mod_ruby.
ruby is trying to load *twice* the same module 'singleton.rb' : it do this
because it don't have the same path, or name, or version, for singleton.rb
svg% cat b.rb
#!/usr/bin/ruby
require 'singleton'
class Something
include Singleton
end
require 'log4r'
svg%
svg% b.rb
svg%
Now
svg% cat b.rb
#!/usr/bin/ruby
require '/usr/local/lib/ruby/1.8/singleton.rb'
class Something
include Singleton
end
require 'log4r'
svg%
svg% b.rb
/usr/local/lib/ruby/1.8/singleton.rb:119: warning: already initialized constant FirstInstanceCall
/usr/local/lib/ruby/1.8/singleton.rb:161:in `undef_method': undefined method `extend_object' for `Singleton' (NameError)
from /usr/local/lib/ruby/1.8/singleton.rb:161
from /usr/local/lib/ruby/site_ruby/1.8/log4r/repository.rb:4:in `require'
from /usr/local/lib/ruby/site_ruby/1.8/log4r/repository.rb:4
from /usr/local/lib/ruby/site_ruby/1.8/log4r/outputter/outputterfactory.rb:5:in `require'
from /usr/local/lib/ruby/site_ruby/1.8/log4r/outputter/outputterfactory.rb:5
from /usr/local/lib/ruby/site_ruby/1.8/log4r/outputter/outputter.rb:10:in `require'
from /usr/local/lib/ruby/site_ruby/1.8/log4r/outputter/outputter.rb:10
from /usr/local/lib/ruby/site_ruby/1.8/log4r/outputter/iooutputter.rb:2:in `require'
from /usr/local/lib/ruby/site_ruby/1.8/log4r/outputter/iooutputter.rb:2
from /usr/local/lib/ruby/site_ruby/1.8/log4r/outputter/fileoutputter.rb:4:in `require'
from /usr/local/lib/ruby/site_ruby/1.8/log4r/outputter/fileoutputter.rb:4
from /usr/local/lib/ruby/site_ruby/1.8/log4r.rb:8:in `require'
from /usr/local/lib/ruby/site_ruby/1.8/log4r.rb:8
from ./b.rb:6:in `require'
from ./b.rb:6
svg%
For ruby
require '/usr/local/lib/ruby/1.8/singleton.rb'
is different (it think that it's another module)
require 'singleton' # which is in repository.rb
This is why it give an error
Another reason is that you mix
* ruby 1.8.0
* mod_ruby built with ruby 1.6.8
…and since those three lines work just fine in IRB, I suspect
something fishy with mod_ruby.
Another reason is that you mix
ruby 1.8.0
mod_ruby built with ruby 1.6.8
I didn’t. Just double-checked it and even recompiled mod_ruby (1.1.1)
and installed it again. It’s surely ruby 1.8.0 and mod_ruby 1.1.1
compiled with the same version.
ruby 1.8.0 installs its libraries in a different place… so just to be
sure, try
puts RUBY_VERSION
in your mod_ruby application and see what it reports.
Cheers,
Brian.
···
On Tue, Aug 05, 2003 at 08:22:39PM +0900, David Heinemeier Hansson wrote:
Another reason is that you mix
ruby 1.8.0
mod_ruby built with ruby 1.6.8
I didn’t. Just double-checked it and even recompiled mod_ruby (1.1.1)
and installed it again. It’s surely ruby 1.8.0 and mod_ruby 1.1.1
compiled with the same version.
I didn't. Just double-checked it and even recompiled mod_ruby (1.1.1)
and installed it again. It's surely ruby 1.8.0 and mod_ruby 1.1.1
compiled with the same version.
I always thought this isn’t done, so the programmer isn’t deluded a
false sense of security: There isn’t always the cannonical
path. Think of filesystems that ignore the case in filenames. (Not to
mention (symbolic and hard) links or alias names (single~1.rb)
···
On Tue, Aug 05, 2003 at 11:09:19PM +0900, Dave Thomas wrote:
ts wrote:
require ‘/usr/local/lib/ruby/1.8/singleton.rb’
is different (it think that it’s another module)
require ‘singleton’ # which is in repository.rb
I have never understood this: why doesn’t Ruby store the cannonical
(fully expanded) path name; that would eliminate this kind of problem.
ruby 1.8.0 installs its libraries in a different place… so just to be
sure, try
puts RUBY_VERSION
in your mod_ruby application and see what it reports.
I’ve reduced the test case to this:
singleton.rbx:
require “singleton”
That doesn’t work (same complaining about trying to import the same
class twice). This does, though:
require “/usr/local/lib/ruby/1.6/singleton.rb”
But “puts RUBY_VERSION” from a .rbx gives me 1.8.0, so it must be
running from the newest version. But mod_ruby is obviously still using
the 1.6 singleton.rb file. I just can’t figure out why.
I have never understood this: why doesn’t Ruby store the cannonical
(fully expanded) path name; that would eliminate this kind of problem.
I always thought this isn’t done, so the programmer isn’t deluded a
false sense of security: There isn’t always the cannonical
path. Think of filesystems that ignore the case in filenames. (Not to
mention (symbolic and hard) links or alias names (single~1.rb)
Would it be worse than it is now?
Why couldn’t Ruby make the name cannonical. On a Unix-based box, for
example, it could store the i-node number. Surely every operating system
has some way to get to a single target identifier for a given file?
I see the argument, but I don’t really like it. One thing I like about
Java (which seems more OO than Ruby) is that when you import something,
what you’re specifying is classes rather than files. I like this idea
because the classes are what you really care about anyhow.
Another problem which is starting to pop up is versioning. In Perl you
can require that what you’re using has a certain version number. This
is a good “sanity check” when you’re using libraries which may
fluctuate (like the CGI one for example).
Is it too late to come up with an alternative to ‘require’?
Ben
···
On Tuesday, August 5, 2003, at 10:35 AM, Marko Schulz wrote:
On Tue, Aug 05, 2003 at 11:09:19PM +0900, Dave Thomas wrote:
I have never understood this: why doesn’t Ruby store the cannonical
(fully expanded) path name; that would eliminate this kind of problem.
I always thought this isn’t done, so the programmer isn’t deluded a
false sense of security: There isn’t always the cannonical
path. Think of filesystems that ignore the case in filenames. (Not to
mention (symbolic and hard) links or alias names (single~1.rb)
I see the argument, but I don’t really like it. One thing I like about
Java (which seems more OO than Ruby) is that when you import something,
what you’re specifying is classes rather than files. I like this idea
Only because Java enforces a given directory structure. If you had the
same constraint in Ruby, require would be similar to import.
Is it too late to come up with an alternative to ‘require’?
Nothing prevents you from writing it, making it compatible with require
and getting some people to use it
···
On Tue, Aug 05, 2003 at 11:50:07PM +0900, Ben Giddings wrote:
I always thought this isn’t done, so the programmer isn’t deluded a
false sense of security: There isn’t always the cannonical
path. Think of filesystems that ignore the case in filenames. (Not to
mention (symbolic and hard) links or alias names (single~1.rb)
Would it be worse than it is now?
Depends on whether you think false security is better than no
security.
Why couldn’t Ruby make the name cannonical. On a Unix-based
box, for example, it could store the i-node number.
Technically, it would have to be the pair (device, i-node number),
but it’s a good thought. If the file to be loaded has the same
(d,i) as a file already loaded, don’t load it again. It would
require more OS-specific code in the loader, though.
Surely every operating system
has some way to get to a single target identifier for a given file?
I would be wary of making such an assumption. It seems logical,
but OSes are often illogical creatures, at least on the surface.
-Mark
···
On Tue, Aug 05, 2003 at 11:46:07PM +0900, Dave Thomas wrote:
I have never understood this: why doesn’t Ruby store the cannonical
(fully expanded) path name; that would eliminate this kind of problem.
I always thought this isn’t done, so the programmer isn’t deluded a
false sense of security: There isn’t always the cannonical
path. Think of filesystems that ignore the case in filenames. (Not to
mention (symbolic and hard) links or alias names (single~1.rb)
Would it be worse than it is now?
If there is a solution: Great!
I don’t really have enough cross-platform knowledge to decide whether
it is possible; but on the platforms I know, it already seems awkward,
to detect for sure, whether a file already has been read (maybe
somebody should look how others do it):
Why couldn’t Ruby make the name cannonical. On a Unix-based box, for
example, it could store the i-node number.
Besides the number of the i-node you would at least have to store the
mount point (or the device?). Here I have to files on different
devices with the same inode:
$ ls -di /usr/include/netax25 /home/marko/musik/Farin_Urlaub/Endlich_Urlaub
374641 /home/marko/musik/Farin_Urlaub/Endlich_Urlaub
374641 /usr/include/netax25
But even then, I wouldn’t be sure, that every filesystem on every
unices uses reliable i-node numbers.
Under Linux they are at least not stable across remounts for a FAT-FS:
$ ls -i /mnt/dos/autoexec.bat
67756 /mnt/dos/autoexec.bat
$ sudo umount /mnt/dos/
$ sudo mount /mnt/dos/
$ ls -i /mnt/dos/autoexec.bat
67757 /mnt/dos/autoexec.bat
Surely every operating system
has some way to get to a single target identifier for a given file?
Maybe just storing the full path is already enough (resolving all …/'s
and maybe symlinks). Maybe storing a md5sum for each file is enough.
Maybe somebody just has to try it.
···
On Tue, Aug 05, 2003 at 11:46:07PM +0900, Dave Thomas wrote:
I don’t really have enough cross-platform knowledge to decide whether
it is possible; but on the platforms I know, it already seems awkward,
to detect for sure, whether a file already has been read (maybe
somebody should look how others do it):
In C, the file itself is responsible for this:
#ifndef _myheader_h #define _myheader_h
… do stuff #endif
Maybe storing a md5sum for each file is enough.
Cool idea, except the cost of reading in a file every time you see
require ‘foo’
means that it would break things. I quite happily put a ‘require’ buried
inside a loop at the moment, knowing that the library will get read just the
first time it’s needed.
Cheers,
Brian.
···
On Wed, Aug 06, 2003 at 01:06:46AM +0900, Marko Schulz wrote:
You would also need the constraint that files and classes be named
the same. I am tending towards that constraint in my own code anyway,
primarily so the target of ‘require’ resolves as a ctag, easing
navigation.
Another difference between Java and Ruby here: Java allows only one
“public” class in each file. Not that Ruby has the concept of
packages anyway.
Gavin
···
On Wednesday, August 6, 2003, 1:01:44 AM, Mauricio wrote:
On Tue, Aug 05, 2003 at 11:50:07PM +0900, Ben Giddings wrote:
I see the argument, but I don’t really like it. One thing I like about
Java (which seems more OO than Ruby) is that when you import something,
what you’re specifying is classes rather than files. I like this idea
Only because Java enforces a given directory structure. If you had the
same constraint in Ruby, require would be similar to import.