Skip to content

Instantly share code, notes, and snippets.

@apotonick
Last active December 11, 2015 21:29
Show Gist options
  • Save apotonick/4662983 to your computer and use it in GitHub Desktop.
Save apotonick/4662983 to your computer and use it in GitHub Desktop.
The problem here is the instance_exec in the anonymous module - the #a method is not mixed into obj.
blk = lambda { def a; end }
mod = Module.new { instance_exec &blk } # this should add #a to mod.
obj = Object.new
obj.extend(mod)
obj.a #=> undefined method `a' for #<Object:0x970543c>
@gregkare
Copy link

Mmmh, I can't make this work (tried in 1.9.3 and 1.8.7):

>> blk = lambda { def a; end }
=> #<Proc:0x007fddbc13e920@(irb):1 (lambda)>
>> mod = Module.new { instance_exec blk }
LocalJumpError: no block given
    from (irb):2:in `instance_exec'
    from (irb):2:in `block in irb_binding'
    from (irb):2:in `initialize'
    from (irb):2:in `new'
    from (irb):2

@apotonick
Copy link
Author

I was missing the & in the example: https://twitter.com/godfat/status/296189876804648960

@apotonick
Copy link
Author

Thanks @godfat! It should read

mod = Module.new { module_exec &blk }

@virtualfunction
Copy link

@apotonick, I dunno if this is still is relevant but instance_exec is going to add a as a module function to mod. So it can be called using mod.a

If a was to be included to obj via mod, it would need to exist in mod as a instance method, which ironically means one has to add it via class_exec (mo module_exec).

instance_exec (and eval) define class methods when the context is a module/class
class_exec/module_exec (and eval counter parts) define instance methods

Bloody confusing I know. (See http://ilikestuffblog.com/2009/01/09/fun-with-rubys-instance_eval-and-class_eval/ for a better explanation)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment