Skip to content

Instantly share code, notes, and snippets.

@darscan
Created March 8, 2012 13:00
Show Gist options
  • Save darscan/2000900 to your computer and use it in GitHub Desktop.
Save darscan/2000900 to your computer and use it in GitHub Desktop.
Dynamically adding class methods
# I want to add DynamicClass.some_method, not DynamicClass.new.some_method, so..
class DynamicClass
@@syms = []
def self.metaclass
class << self; self; end
end
def self.add_method(sym)
@@syms.push(sym) unless @@syms.include?(sym)
metaclass.instance_eval do
define_method(sym) do |*p|
yield(*p) if block_given?
end
end
end
def self.remove_method(sym)
@@syms.delete(sym)
metaclass.instance_eval do
remove_method(sym)
end
end
def self.remove_methods!
@@syms.dup.each{|sym| remove_method(sym)}
@@syms = []
end
end
class Foo < DynamicClass; end
def test
Foo.add_method(:delete) {|id| id}
Foo.delete('bar')
end
puts test
@darscan
Copy link
Author

darscan commented Mar 18, 2012

Hey, thanks for checking this out! The thing is that I wanted to be able to add and remove methods during test runs. As far as I know you can't open up a class whilst you're inside a method. The gist sort-of works, but currently suffers from the fact that the @@syms variable is shared by all classes that extend Dynamic class. This was just an experiment in making a small class mocking utility.

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