Skip to content

Instantly share code, notes, and snippets.

@mxgrn
Created October 21, 2010 17:30
Show Gist options
  • Save mxgrn/638919 to your computer and use it in GitHub Desktop.
Save mxgrn/638919 to your computer and use it in GitHub Desktop.
Wrong scope of yield?
# (Ruby version: 1.9.2)
#
##### A million-dollar question: why the following isn't working?
#
#
class A
def self.metamethod(name)
define_method(name) do
yield
end
end
end
class B < A
def m1
"from m1"
end
metamethod :my_method do
m1
end
end
B.new.my_method #=> undefined local variable or method ‘m1’ for B:Class (* B:Class ??? *)
#
#
########### ...while the following does! #############
#
#
class A
def self.metamethod(name)
define_singleton_method(name) do
yield
end
end
end
class B < A
def self.m1
"from m1"
end
metamethod :my_method do
m1
end
end
B.my_method #=> "from m1"
@mxgrn
Copy link
Author

mxgrn commented Nov 12, 2010

The solution was using instance_eval instead of yield:

class A
  def self.metamethod(name, &block)
    define_method(name) do
      instance_eval(&block)
    end
  end
end

class B < A
  def m1
    "from m1"
  end

  metamethod :my_method do
    m1
  end
end

B.new.my_method #=> "from m1"

@p8
Copy link

p8 commented Nov 14, 2010

Nice!

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