0

Why does the following code not raise an error:

Object.new.instance_eval { some_accessor_that_does_not_exist= "a value" }

While the following would raise a NameError as you would expect:

Object.new.instance_eval { some_method_that_doesnt_exist }

Even this would raise an error:

Object.new.instance_eval { self.some_accessor_that_does_not_exist= "a value" }

I've tried this on 1.8.7-p352 as well as 1.9.3-p194 with the same result.

Redbeard
  • 988
  • 5
  • 8

1 Answers1

1
Object.new.instance_eval { some_accessor_that_does_not_exist= "a value" }

This is interpreted as a creation of new local var named some_accessor_that_does_not_exist, not a setter invocation. When you use assignments with implicit receiver, ruby can't know if you wanted to create a local var or call a method, because there's no special syntax for declaring local vars. And so it creates a local var.

But when you use explicit receiver (self.some_accessor_that_does_not_exist), then ruby interprets it as a method and fails.

Sergio Tulentsev
  • 226,338
  • 43
  • 373
  • 367
  • This was a 'doh' moment for me. When I wrote this question I was thinking about things in a method_missing context (trying to resolve a dynamic programming bug) and just didn't process that this is just valid local var setting syntax... Thanks for the clear answer! – Redbeard Jan 04 '13 at 05:26
  • 1
    @Redbeard: It's a pleasure :) – Sergio Tulentsev Jan 04 '13 at 05:27