2

I have a dummy object that always yield itself:

x = Object.new; x.define_singleton_method(:method_missing) { |*| x }

x.foo.bar.baz == x # => true

I wanted to simplify it, but suddenly it doesn't work anymore:

x = Object.new; def x.method_missing(*) x end

x.foo # raises SystemStackError, stack level too deep

Why is a SystemStackError raised in that last example?

Ulysse BN
  • 10,116
  • 7
  • 54
  • 82

1 Answers1

3

Found it!

The def creates a new scope for local variables, whereas the closure keeps local variables.

x = Object.new # declares a local variable `x`
def x.method_missing(*)
  x # actually tries to call the method `x`, which is itself missing.
end
x = 42
p local_variables # => [:x, :b]
def a; local_variables; end
b = -> { local_variables }
p a # => []
p b.call # => [:x, :b]

Per comment, to fix it you could use self, or for a shorter declaration:

X=Object.new;def X.method_missing(*) X end # Global variables are in the global scope
Ulysse BN
  • 10,116
  • 7
  • 54
  • 82