Skip to content

Instantly share code, notes, and snippets.

@mneedham
Created September 10, 2010 04:11
Show Gist options
  • Select an option

  • Save mneedham/573074 to your computer and use it in GitHub Desktop.

Select an option

Save mneedham/573074 to your computer and use it in GitHub Desktop.
Trying to create a little proxy around a class:
class Bar
def self.foo
"mark"
end
end
It works by opening the class:
class Bar
class << self
alias_method :orig, :foo
def foo
p "i am overriden"
orig
end
end
end
But I want to only create the proxy on a method call so trying to use 'define_method' instead:
Bar.send(:alias_method, :orig, :foo)
But that fails saying:
NameError: undefined method `foo' for class `Bar'
from (irb):11:in `alias_method'
from (irb):11:in `send'
from (irb):11
from :0
Must be doing something obvious wrong but not sure what
@joelash
Copy link
Copy Markdown

joelash commented Sep 10, 2010

I think you need call the send on the metaclass of bar. Something like this works....

class Bar
  def self.foo
    "mark"
  end

  def self.metaclass
    class << self; self; end
  end
end

Bar.metaclass.send :alias_method, :orig, :foo
Bar.orig # "mark"`

Copy link
Copy Markdown

ghost commented Sep 10, 2010

foo is not an instance method of Bar so it won't work. You'll need to use instance_eval or class_eval on Bar or the above technique of metaclass (never seen it before, thanks joelash).

@kaiwren
Copy link
Copy Markdown

kaiwren commented Sep 10, 2010

Copy link
Copy Markdown

ghost commented Sep 10, 2010

Ok I get it now. Shouldn't the metaclass be called the eigen class though?

@joelash
Copy link
Copy Markdown

joelash commented Sep 10, 2010

Yes they are synonyms. In my experience you'll hear people call it either.

@joelash
Copy link
Copy Markdown

joelash commented Sep 10, 2010

OK mark just pointed out a typo in my example and I cannot edit it on an iPhone so I'll fix it when I get to a real computer but the secon to last line should be
Bar.metaclass.send :alias_method, :orig, :foo

@kaiwren
Copy link
Copy Markdown

kaiwren commented Sep 10, 2010

joelash: They aren't synonyms, though in ruby they are often used as such. In this case eigenclass would be more accurate iirc, though I used metaclass.

@joelash
Copy link
Copy Markdown

joelash commented Sep 10, 2010

kalwre: you're right I should have been more specific in saying in ruby they're considered synonyms. Thanks for the correction!

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