Bug #555
closedmethod_missing in Gem module removes some necessary methods
Description
=begin
I found something strange in Ruby 1.9 bundled Rubygems(gem_prelude.rb).
(1) there's a method named default_dir in Gem module, which returns a certain directory name
Gem.default_dir
#=> "/Users/matsuda/ruby/lib/ruby/gems/1.9.0"
(2) call a missing method on Gem module to make a method_missing call
Gem.foo
NoMethodError: undefined method foo' for Gem:Module from gem_prelude.rb:192:in
method_missing'
from (irb):12
from /Users/matsuda/ruby/bin/irb19:12:in `'
(3) method_missing undefs Gem::GEM_PRELUDE_METHODS.each methods inside Gem.method_missing -> QuickLoader.load_full_rubygems_library
(4) Gem.default_dir still alives
Gem.default_dir
#=> "/Users/matsuda/ruby/lib/ruby/gems/1.9.0"
(5) invoke method_missing again
Gem.foo
/Users/matsuda/ruby/lib/ruby/1.9.0/rubygems.rb:82: warning: already initialized constant MUTEX
/Users/matsuda/ruby/lib/ruby/1.9.0/rubygems.rb:84: warning: already initialized constant RubyGemsPackageVersion
/Users/matsuda/ruby/lib/ruby/1.9.0/rubygems.rb:89: warning: already initialized constant WIN_PATTERNS
/Users/matsuda/ruby/lib/ruby/1.9.0/rubygems.rb:742: warning: already initialized constant MARSHAL_SPEC_DIR
/Users/matsuda/ruby/lib/ruby/1.9.0/rubygems.rb:744: warning: already initialized constant YAML_SPEC_DIR
NoMethodError: undefined method foo' for Gem:Module from gem_prelude.rb:192:in
method_missing'
from (irb):14
from /Users/matsuda/ruby/bin/irb19:12:in `'
(6) Gem.default_dir disappears!
Gem.default_dir
NameError: undefined method default_dir' for
Gem'
from gem_prelude.rb:78:in undef_method' from gem_prelude.rb:78:in
block in singletonclass'
from gem_prelude.rb:77:in each' from gem_prelude.rb:77:in
singletonclass'
from gem_prelude.rb:76:in load_full_rubygems_library' from gem_prelude.rb:191:in
method_missing'
from (irb):15
from /Users/matsuda/ruby/bin/irb19:12:in `'
I noticed that some gems don't work well on Ruby 1.9 because of this behavior.
Ruby version: revision 19146
gem -v: 1.2.0.1824
=end
Updated by yugui (Yuki Sonoda) about 16 years ago
- Category set to lib
- Target version set to 1.9.0-5
=begin
=end
Updated by yugui (Yuki Sonoda) about 16 years ago
- Target version changed from 1.9.0-5 to 1.9.1 Release Candidate
=begin
=end
Updated by yugui (Yuki Sonoda) about 16 years ago
=begin
I'll ask Eric whether it still happens
=end
Updated by drbrain (Eric Hodel) about 16 years ago
=begin
I think this patch would fix it:
Index: gem_prelude.rb¶
--- gem_prelude.rb (revision 20650)
+++ gem_prelude.rb (working copy)
@@ -172,6 +172,7 @@ if defined?(Gem) then
# with the real RubyGems
GEM_PRELUDE_METHODS = Gem.methods(false)
-
GEM_PRELUDE_METHODS << :method_missing
begin
verbose, debug = $VERBOSE, $DEBUG
but I get a crash:
(gdb) run -v test.rb
Starting program: /usr/local/bin/ruby19 -v test.rb
Reading symbols for shared libraries +++... done
ruby 1.9.1 (2008-12-12 revision 20648) [i386-darwin9.5.0]
[...]
Program received signal EXC_BAD_ACCESS, Could not access memory.
Reason: KERN_PROTECTION_FAILURE at address: 0x0000012c
0x0010f1dd in vm_exec (th=0x200710) at vm.c:1071
1071 epc = cfp->pc - cfp->iseq->iseq_encoded;
(gdb) bt
#0 0x0010f1dd in vm_exec (th=0x200710) at vm.c:1071
#1 0x0010f914 in rb_iseq_eval (iseqval=4094920) at vm.c:1246
#2 0x0002efa9 in ruby_exec_node (n=0x3e7bc8, file=0x0) at eval.c:205
#3 0x000317ee in ruby_run_node (n=0x3e7bc8) at eval.c:233
#4 0x00001f5f in main (argc=3, argv=0x200540) at main.c:35
=end
Updated by drbrain (Eric Hodel) about 16 years ago
=begin
May I commit this patch? It is correct:
Index: gem_prelude.rb¶
--- gem_prelude.rb (revision 20650)
+++ gem_prelude.rb (working copy)
@@ -194,7 +194,13 @@ if defined?(Gem) then
module QuickLoader
-
@loaded_full_rubygems_library = false
-
def self.load_full_rubygems_library
-
return if @loaded_full_rubygems_library
-
@loaded_full_rubygems_library = true
-
class << Gem Gem::GEM_PRELUDE_METHODS.each do |method_name| undef_method method_name
It passes this test:
$ cat test.rb
Gem.foo rescue nil
Gem.foo rescue nil
p Gem.default_dir
$ ruby19 -v test.rb
ruby 1.9.1 (2008-12-12 revision 20648) [i386-darwin9.5.0]
"/usr/local/lib/ruby19/gems/1.9.1"
=end
Updated by drbrain (Eric Hodel) almost 16 years ago
- Status changed from Open to Closed
- % Done changed from 0 to 100
=begin
Applied in changeset r20923.
=end