Skip to content

Instantly share code, notes, and snippets.

@wycats
Created January 18, 2009 07:53
Show Gist options
  • Save wycats/48571 to your computer and use it in GitHub Desktop.
Save wycats/48571 to your computer and use it in GitHub Desktop.
module TrackAddedMethods
def method_added(meth)
@__added_methods ||= []
@__added_methods << meth
end
def __added_methods
@__added_methods
end
end
class Module
inline do |builder|
builder.include "\"node.h\""
builder.c <<-C
VALUE copy_method(VALUE klass, VALUE symbol) {
ID id = rb_to_id(symbol);
NODE *node = NULL;
st_table *other_method_table = RCLASS(klass)->m_tbl;
st_table *method_table = RCLASS(self)->m_tbl;
if(st_lookup(other_method_table, id, (void *)&node)) {
st_insert(method_table, (st_data_t)id, (st_data_t)node);
return Qtrue;
} else {
rb_raise(rb_eRuntimeError, "No such method `%s' on %s", rb_id2name(id), STR2CSTR(rb_mod_name(klass)));
}
}
C
end
def __move_to_module(*meth_names)
me = self
mod = Module.new do
meth_names.each do |name|
copy_method me, name
end
end
meth_names.each do |name|
remove_method name
end
include mod
end
def override(&blk)
mod = Module.new do
extend TrackAddedMethods
end
mod.class_eval(&blk)
__move_to_module(*mod.__added_methods)
include mod
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment