Bug #555
method_missing in Gem module removes some necessary methods
| Status: | Closed | Start date: | 09/10/2008 | |
|---|---|---|---|---|
| Priority: | Normal | Due date: | 12/24/2008 | |
| Assignee: | % Done: | 100% |
||
| Category: | lib | |||
| Target version: | 1.9.1 Release Candidate | |||
| ruby -v: |
Description
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 `<main>'
(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 `<main>'
(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 `<main>'
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
Associated revisions
Don't remove methods twice. [bug#555]
History
Updated by Koichi Sasada over 3 years ago
- Assignee set to Eric Hodel
Updated by Yuki Sonoda over 3 years ago
- Category set to lib
- Target version set to 1.9.0-5
Updated by Yuki Sonoda about 3 years ago
- Target version changed from 1.9.0-5 to 1.9.1 Release Candidate
Updated by Yuki Sonoda about 3 years ago
I'll ask Eric whether it still happens
Updated by Eric Hodel about 3 years ago
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
Updated by Eric Hodel about 3 years ago
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"
Updated by Yuki Sonoda about 3 years ago
- Due date set to 12/24/2008
Updated by Eric Hodel about 3 years ago
- Status changed from Open to Closed
- % Done changed from 0 to 100
Applied in changeset r20923.