Skip to content

Instantly share code, notes, and snippets.

@pasberth
Created August 16, 2011 01:06
Show Gist options
  • Save pasberth/1148237 to your computer and use it in GitHub Desktop.
Save pasberth/1148237 to your computer and use it in GitHub Desktop.
dynamic define method with ruby 1.8.7
# -*- coding: utf-8 -*-
class Object
def self.define_method(funcname, *params, &blk)
@@methods ||= {}
@@methods[funcname.to_sym] = blk
class_eval(<<DEFINE)
def #{funcname} #{params.join(', ')}
b = binding
def b.method_missing(varname, *args)
$temporary_args = args
if args.empty?
ret = eval("\#\{varname\}")
else
ret = eval("\#\{varname\}(*$temporary_args)")
end
$temporary_args = nil
ret
end
b.instance_eval(&(@@methods[:#{funcname.to_sym}]))
end
DEFINE
end
def define_singleton_method(funcname, *params, &blk)
@instance_methods ||= {}
@instance_methods[funcname.to_sym] = blk
instance_eval(<<DEFINE)
def #{funcname} #{params.join(', ')}
b = binding
def b.method_missing(varname, *args)
$temporary_args = args
if args.empty?
ret = eval("\#\{varname\}")
else
ret = eval("\#\{varname\}(*$temporary_args)")
end
$temporary_args = nil
ret
end
b.instance_eval(&(@instance_methods[:#{funcname.to_sym}]))
end
DEFINE
end
end
if __FILE__ == $PROGRAM_NAME
require 'test/unit'
class TestDefineMethod < Test::Unit::TestCase
def setup
str = "hello"
Object.define_method(:homuhomu_method, :arg0, :arg1) {
arg0 + arg1
}
@obj = Object.new
@obj.define_singleton_method(:homuhomu_singleton_method, :arg0, :arg1) {
arg0 + arg1
}
@obj.define_singleton_method(:homuhomu_wrapper, :arg0, :arg1) {
homuhomu_singleton_method arg0, arg1
}
@obj.define_singleton_method(:homuhomu_closure) {
str
}
end
def test_define_method
assert_equal(10, @obj.homuhomu_method(5, 5))
end
def test_define_singleton_method
assert_equal(10, @obj.homuhomu_singleton_method(5, 5))
end
def test_wrapper
assert_equal(10, @obj.homuhomu_wrapper(5, 5))
end
def test_closure
assert_equal("hello", @obj.homuhomu_closure)
end
def test_string
assert_equal("abcdefg", @obj.homuhomu_method("abcd", "efg"))
end
def test_object
assert_equal([1, 2, 3, 4, 5], @obj.homuhomu_method([1, 2], [3, 4, 5]))
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment