diff options
| author | Yukihiro "Matz" Matsumoto <[email protected]> | 2013-01-04 03:25:50 -0800 |
|---|---|---|
| committer | Yukihiro "Matz" Matsumoto <[email protected]> | 2013-01-04 03:25:50 -0800 |
| commit | db2fed84d1414331b95f30d84912295a276c4837 (patch) | |
| tree | 53a1947c1ce64894cb4e34a207babf06a09ed5f3 | |
| parent | 5df3a9dbdf947e4f0222b92d29c213fb48f53821 (diff) | |
| parent | c4995884e6209d837bae46e4547202352f7436d8 (diff) | |
| download | mruby-db2fed84d1414331b95f30d84912295a276c4837.tar.gz mruby-db2fed84d1414331b95f30d84912295a276c4837.zip | |
Merge pull request #686 from skandhas/pr-add-Module-method_defined
Add Module#method_defined? for mruby
| -rw-r--r-- | src/class.c | 43 | ||||
| -rw-r--r-- | test/t/module.rb | 24 |
2 files changed, 67 insertions, 0 deletions
diff --git a/src/class.c b/src/class.c index ace34eb34..ea0db2bdc 100644 --- a/src/class.c +++ b/src/class.c @@ -1595,6 +1595,48 @@ mrb_mod_remove_cvar(mrb_state *mrb, mrb_value mod) return mrb_nil_value(); } +/* 15.2.2.4.34 */ +/* + * call-seq: + * mod.method_defined?(symbol) -> true or false + * + * Returns +true+ if the named method is defined by + * _mod_ (or its included modules and, if _mod_ is a class, + * its ancestors). Public and protected methods are matched. + * + * module A + * def method1() end + * end + * class B + * def method2() end + * end + * class C < B + * include A + * def method3() end + * end + * + * A.method_defined? :method1 #=> true + * C.method_defined? "method1" #=> true + * C.method_defined? "method2" #=> true + * C.method_defined? "method3" #=> true + * C.method_defined? "method4" #=> false + */ + +static mrb_value +mrb_mod_method_defined(mrb_state *mrb, mrb_value mod) +{ + mrb_value sym; + mrb_sym id; + + mrb_get_args(mrb, "o", &sym); + id = mrb_sym_value(mrb,sym); + + if (mrb_obj_respond_to(mrb_class_ptr(mod), id)) { + return mrb_true_value(); + } + return mrb_false_value(); +} + static void remove_method(mrb_state *mrb, struct RClass *c, mrb_sym mid) { @@ -1750,6 +1792,7 @@ mrb_init_class(mrb_state *mrb) mrb_define_method(mrb, mod, "included", mrb_bob_init, ARGS_REQ(1)); /* 15.2.2.4.29 */ mrb_define_method(mrb, mod, "included_modules", mrb_mod_included_modules, ARGS_NONE()); /* 15.2.2.4.30 */ mrb_define_method(mrb, mod, "instance_methods", mrb_mod_instance_methods, ARGS_ANY()); /* 15.2.2.4.33 */ + mrb_define_method(mrb, mod, "method_defined?", mrb_mod_method_defined, ARGS_REQ(1)); /* 15.2.2.4.34 */ mrb_define_method(mrb, mod, "module_eval", mrb_mod_module_eval, ARGS_ANY()); /* 15.2.2.4.35 */ mrb_define_method(mrb, mod, "remove_class_variable", mrb_mod_remove_cvar, ARGS_REQ(1)); /* 15.2.2.4.39 */ mrb_define_method(mrb, mod, "remove_method", mrb_mod_remove_method, ARGS_ANY()); /* 15.2.2.4.41 */ diff --git a/test/t/module.rb b/test/t/module.rb index bf9626c2d..286c2c085 100644 --- a/test/t/module.rb +++ b/test/t/module.rb @@ -199,6 +199,30 @@ assert('Module#instance_methods', '15.2.2.4.33') do r.class == Array and r.include?(:method3) and r.include?(:method2) end +assert('Module#method_defined?', '15.2.2.4.34') do + module Test4MethodDefined + module A + def method1() end + end + + class B + def method2() end + end + + class C < B + include A + def method3() end + end + end + + Test4MethodDefined::A.method_defined? :method1 and + Test4MethodDefined::C.method_defined? :method1 and + Test4MethodDefined::C.method_defined? "method2" and + Test4MethodDefined::C.method_defined? "method3" and + not Test4MethodDefined::C.method_defined? "method4" +end + + assert('Module#module_eval', '15.2.2.4.35') do module Test4ModuleEval @a = 11 |
