summaryrefslogtreecommitdiff
path: root/test/ruby
diff options
context:
space:
mode:
authorusa <usa@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2018-08-13 12:42:03 +0000
committerusa <usa@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2018-08-13 12:42:03 +0000
commitbccb24a866b453ce17b797ea0f297f053983b5b3 (patch)
treee66fc70fe55296d91d2ef7b3d53a8eadfdfb1702 /test/ruby
parent50e41f4a4fc2ba5a001536845b44d52010791237 (diff)
Support optional inherit argument for Module#method_defined?
Module has many introspection methods for methods and constants that either return an array or return true or false for whether the method or constant is defined. Most of these methods support an optional argument that controls whether to consider inheritance. Currently, the following Module methods support such a argument: * const_defined? * constants * instance_methods * private_instance_methods * protected_instance_methods * public_instance_methods and the following methods do not: * method_defined? * private_method_defined? * protected_method_defined? * public_method_defined? This patch supports such an argument for the *method_defined? methods. While you can currently work around the lack of support via: mod.instance_methods(false).include?(:method_name) This patch allows the simpler and more efficient: mod.method_defined?(:method_name, false) One case where you want to exclude inheritance when checking for a method definition is when you want to replace a method that may already exist. To avoid a verbose warning, you want to remove the method only if it is already defined: remove_method(:foo) if method_defined?(:foo, false) define_method(:foo){} You can't call remove_method without checking for the method definition, as that can raise a NameError, and you don't want to include inheritance because remove_method will still raise a NameError if the method is defined by an ancestor and not by the module itself. [ruby-core:88140] [Feature #14944] From: Jeremy Evans <code@jeremyevans.net> git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@64337 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'test/ruby')
-rw-r--r--test/ruby/test_module.rb105
1 files changed, 72 insertions, 33 deletions
diff --git a/test/ruby/test_module.rb b/test/ruby/test_module.rb
index 08254605cf..15a39346dd 100644
--- a/test/ruby/test_module.rb
+++ b/test/ruby/test_module.rb
@@ -468,17 +468,42 @@ class TestModule < Test::Unit::TestCase
end
def test_method_defined?
- assert !User.method_defined?(:wombat)
- assert User.method_defined?(:mixin)
- assert User.method_defined?(:user)
- assert User.method_defined?(:user2)
- assert !User.method_defined?(:user3)
+ [User, Class.new{include User}, Class.new{prepend User}].each do |klass|
+ [[], [true]].each do |args|
+ assert !klass.method_defined?(:wombat, *args)
+ assert klass.method_defined?(:mixin, *args)
+ assert klass.method_defined?(:user, *args)
+ assert klass.method_defined?(:user2, *args)
+ assert !klass.method_defined?(:user3, *args)
- assert !User.method_defined?("wombat")
- assert User.method_defined?("mixin")
- assert User.method_defined?("user")
- assert User.method_defined?("user2")
- assert !User.method_defined?("user3")
+ assert !klass.method_defined?("wombat", *args)
+ assert klass.method_defined?("mixin", *args)
+ assert klass.method_defined?("user", *args)
+ assert klass.method_defined?("user2", *args)
+ assert !klass.method_defined?("user3", *args)
+ end
+ end
+ end
+
+ def test_method_defined_without_include_super
+ assert User.method_defined?(:user, false)
+ assert !User.method_defined?(:mixin, false)
+ assert Mixin.method_defined?(:mixin, false)
+
+ User.const_set(:FOO, c = Class.new)
+
+ c.prepend(User)
+ assert !c.method_defined?(:user, false)
+ c.define_method(:user){}
+ assert c.method_defined?(:user, false)
+
+ assert !c.method_defined?(:mixin, false)
+ c.define_method(:mixin){}
+ assert c.method_defined?(:mixin, false)
+
+ assert !c.method_defined?(:userx, false)
+ c.define_method(:userx){}
+ assert c.method_defined?(:userx, false)
end
def module_exec_aux
@@ -974,8 +999,8 @@ class TestModule < Test::Unit::TestCase
end
def test_method_defined
- c = Class.new
- c.class_eval do
+ cl = Class.new
+ def_methods = proc do
def foo; end
def bar; end
def baz; end
@@ -983,33 +1008,47 @@ class TestModule < Test::Unit::TestCase
protected :bar
private :baz
end
+ cl.class_eval(&def_methods)
+ sc = Class.new(cl)
+ mod = Module.new(&def_methods)
+ only_prepend = Class.new{prepend(mod)}
+ empty_prepend = cl.clone
+ empty_prepend.prepend(Module.new)
+ overlap_prepend = cl.clone
+ overlap_prepend.prepend(mod)
- assert_equal(true, c.public_method_defined?(:foo))
- assert_equal(false, c.public_method_defined?(:bar))
- assert_equal(false, c.public_method_defined?(:baz))
+ [[], [true], [false]].each do |args|
+ [cl, sc, only_prepend, empty_prepend, overlap_prepend].each do |c|
+ always_false = [sc, only_prepend].include?(c) && args == [false]
- # Test if string arguments are converted to symbols
- assert_equal(true, c.public_method_defined?("foo"))
- assert_equal(false, c.public_method_defined?("bar"))
- assert_equal(false, c.public_method_defined?("baz"))
+ assert_equal(always_false ? false : true, c.public_method_defined?(:foo, *args))
+ assert_equal(always_false ? false : false, c.public_method_defined?(:bar, *args))
+ assert_equal(always_false ? false : false, c.public_method_defined?(:baz, *args))
- assert_equal(false, c.protected_method_defined?(:foo))
- assert_equal(true, c.protected_method_defined?(:bar))
- assert_equal(false, c.protected_method_defined?(:baz))
+ # Test if string arguments are converted to symbols
+ assert_equal(always_false ? false : true, c.public_method_defined?("foo", *args))
+ assert_equal(always_false ? false : false, c.public_method_defined?("bar", *args))
+ assert_equal(always_false ? false : false, c.public_method_defined?("baz", *args))
- # Test if string arguments are converted to symbols
- assert_equal(false, c.protected_method_defined?("foo"))
- assert_equal(true, c.protected_method_defined?("bar"))
- assert_equal(false, c.protected_method_defined?("baz"))
+ assert_equal(always_false ? false : false, c.protected_method_defined?(:foo, *args))
+ assert_equal(always_false ? false : true, c.protected_method_defined?(:bar, *args))
+ assert_equal(always_false ? false : false, c.protected_method_defined?(:baz, *args))
- assert_equal(false, c.private_method_defined?(:foo))
- assert_equal(false, c.private_method_defined?(:bar))
- assert_equal(true, c.private_method_defined?(:baz))
+ # Test if string arguments are converted to symbols
+ assert_equal(always_false ? false : false, c.protected_method_defined?("foo", *args))
+ assert_equal(always_false ? false : true, c.protected_method_defined?("bar", *args))
+ assert_equal(always_false ? false : false, c.protected_method_defined?("baz", *args))
- # Test if string arguments are converted to symbols
- assert_equal(false, c.private_method_defined?("foo"))
- assert_equal(false, c.private_method_defined?("bar"))
- assert_equal(true, c.private_method_defined?("baz"))
+ assert_equal(always_false ? false : false, c.private_method_defined?(:foo, *args))
+ assert_equal(always_false ? false : false, c.private_method_defined?(:bar, *args))
+ assert_equal(always_false ? false : true, c.private_method_defined?(:baz, *args))
+
+ # Test if string arguments are converted to symbols
+ assert_equal(always_false ? false : false, c.private_method_defined?("foo", *args))
+ assert_equal(always_false ? false : false, c.private_method_defined?("bar", *args))
+ assert_equal(always_false ? false : true, c.private_method_defined?("baz", *args))
+ end
+ end
end
def test_top_public_private