Project

General

Profile

Actions

Bug #5077

closed

method_missing throws NoMemoryError after inheriting from BasicObject

Added by madtrick (Farruco Sanjurjo) over 13 years ago. Updated over 13 years ago.

Status:
Rejected
Assignee:
-
Target version:
ruby -v:
ruby 1.9.2p290 (2011-07-09 revision 32478) [x86_64-linux]
Backport:
[ruby-core:38394]

Description

If a class inherits from BasicObject and then overwrites method_missing like this:

class A < BasicObject
def method_missing(*a)
puts "#{a}"
end
end

And we try it:

A.new.fooooo

The interpreter enters what looks like a loop and then crashes with this trace (in irb):

NoMemoryError: failed to allocate memory
from (irb):3:in method_missing' from (irb):3:in method_missing'
from (irb):3:in method_missing' from (irb):3:in method_missing'
from (irb):3:in method_missing' from (irb):3:in method_missing'
from (irb):3:in method_missing' from (irb):3:in method_missing'
from (irb):3:in method_missing' from (irb):3:in method_missing'
from (irb):3:in method_missing' from (irb):3:in method_missing'
from (irb):3:in method_missing' from (irb):3:in method_missing'
from (irb):3:in method_missing' from (irb):3:in method_missing'
from (irb):3:in method_missing' from (irb):3:in method_missing'
from (irb):3:in method_missing' from (irb):3:in method_missing'
from (irb):3:in method_missing' from (irb):3:in method_missing'
from (irb):3:in method_missing' from (irb):3:in method_missing'
from (irb):3:in method_missing' from (irb):3:in method_missing'
from (irb):3:in method_missing' from (irb):3:in method_missing'
from (irb):3:in method_missing' from (irb):3:in method_missing'

If we create the same class with the same method_missing but without inheriting from BasicObject it works right.

Updated by Eregon (Benoit Daloze) over 13 years ago

Farruco Sanjurjo wrote:

If a class inherits from BasicObject and then overwrites method_missing like this:

class A < BasicObject
def method_missing(*a)
puts "#{a}"
end
end

And we try it:

A.new.fooooo

The interpreter enters what looks like a loop and then crashes with this trace (in irb):

method_missing is called indefinitely recursively because "puts" is not a method in BasicObject.

Only methods available in BasicObject are:
BasicObject.instance_methods # => [:==, :equal?, :!, :!=, :instance_eval, :instance_exec, :send]

"puts" is usually provided by Kernel#puts. But Kernel is not included in BasicObject.
You could solve this two ways:

  • use "::Kernel::puts" instead of "puts" (the documentation about the first :: is being discussed in Bug #5067)
  • include Kernel into your class A

Updated by mrkn (Kenta Murata) over 13 years ago

  • Status changed from Open to Rejected
  • Priority changed from 5 to Normal

BasicObject doesn't include Kernel module.
It is a spec.

Actions

Also available in: Atom PDF

Like0
Like0Like0