Project

General

Profile

Actions

Bug #555

closed

method_missing in Gem module removes some necessary methods

Added by matsuda (Akira Matsuda) over 15 years ago. Updated almost 13 years ago.

Status:
Closed
ruby -v:
Backport:
[ruby-core:18527]

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

Actions #1

Updated by ko1 (Koichi Sasada) over 15 years ago

  • Assignee set to drbrain (Eric Hodel)

=begin

=end

Actions #2

Updated by yugui (Yuki Sonoda) over 15 years ago

  • Category set to lib
  • Target version set to 1.9.0-5

=begin

=end

Actions #3

Updated by yugui (Yuki Sonoda) over 15 years ago

  • Target version changed from 1.9.0-5 to 1.9.1 Release Candidate

=begin

=end

Actions #4

Updated by yugui (Yuki Sonoda) over 15 years ago

=begin
I'll ask Eric whether it still happens
=end

Actions #5

Updated by drbrain (Eric Hodel) over 15 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

Actions #6

Updated by drbrain (Eric Hodel) over 15 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

Actions #7

Updated by yugui (Yuki Sonoda) over 15 years ago

  • Due date set to 12/24/2008

=begin

=end

Actions #8

Updated by drbrain (Eric Hodel) over 15 years ago

  • Status changed from Open to Closed
  • % Done changed from 0 to 100

=begin
Applied in changeset r20923.
=end

Actions

Also available in: Atom PDF

Like0
Like0Like0Like0Like0Like0Like0Like0Like0