summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog5
-rw-r--r--NEWS15
-rw-r--r--test/ruby/test_method.rb58
-rw-r--r--vm_method.c5
4 files changed, 81 insertions, 2 deletions
diff --git a/ChangeLog b/ChangeLog
index 8698b396d7..67c0d1fbae 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+Mon Jul 5 16:05:39 2010 Akinori MUSHA <knu@iDaemons.org>
+
+ * vm_method.c (rb_method_boundp): Return false for protected
+ methods when called from Kernel#respond_to?. [ruby-dev:40461]
+
Mon Jul 5 12:32:01 2010 Aaron Patterson <aaron@tenderlovemaking.com>
* ext/psych/lib/psych/scalar_scanner.rb (parse_string): support
diff --git a/NEWS b/NEWS
index ab1e9c0edd..9c2fc05c90 100644
--- a/NEWS
+++ b/NEWS
@@ -8,6 +8,21 @@ Note that each entry is kept so brief that no reason behind or
reference information is supplied with. For a full list of changes
with all sufficient information, see the ChangeLog file.
+== Changes since the 1.9.2 release
+=== Library updates (outstanding ones only)
+
+* builtin classes
+
+ * Kernel
+
+ * Kernel#respond_to? now returns false for protected methods.
+
+=== Compatibility issues (excluding feature bug fixes)
+
+* Kernel#respond_to?
+
+ See above.
+
== Changes since the 1.9.1 release
=== Library updates (outstanding ones only)
diff --git a/test/ruby/test_method.rb b/test/ruby/test_method.rb
index 7be70b00a6..61f523e4e1 100644
--- a/test/ruby/test_method.rb
+++ b/test/ruby/test_method.rb
@@ -39,6 +39,20 @@ class TestMethod < Test::Unit::TestCase
def meth; end
end
+ def mv1() end
+ def mv2() end
+ private :mv2
+ def mv3() end
+ protected :mv3
+
+ class Visibility
+ def mv1() end
+ def mv2() end
+ private :mv2
+ def mv3() end
+ protected :mv3
+ end
+
def test_arity
assert_equal(0, method(:m0).arity)
assert_equal(1, method(:m1).arity)
@@ -345,4 +359,48 @@ class TestMethod < Test::Unit::TestCase
obj.extend(m)
assert_equal([:m1, :a], obj.public_methods(false), bug)
end
+
+ def test_visibility
+ assert_equal('method', defined?(mv1))
+ assert_equal('method', defined?(mv2))
+ assert_equal('method', defined?(mv3))
+
+ assert_equal('method', defined?(self.mv1))
+ assert_equal(nil, defined?(self.mv2))
+ assert_equal('method', defined?(self.mv3))
+
+ assert_equal(true, respond_to?(:mv1))
+ assert_equal(false, respond_to?(:mv2))
+ assert_equal(false, respond_to?(:mv3))
+
+ assert_nothing_raised { mv1 }
+ assert_nothing_raised { mv2 }
+ assert_nothing_raised { mv3 }
+
+ assert_nothing_raised { self.mv1 }
+ assert_raise(NoMethodError) { self.mv2 }
+ assert_nothing_raised { self.mv3 }
+
+ v = Visibility.new
+
+ assert_equal('method', defined?(v.mv1))
+ assert_equal(nil, defined?(v.mv2))
+ assert_equal(nil, defined?(v.mv3))
+
+ assert_equal(true, v.respond_to?(:mv1))
+ assert_equal(false, v.respond_to?(:mv2))
+ assert_equal(false, v.respond_to?(:mv3))
+
+ assert_nothing_raised { v.mv1 }
+ assert_raise(NoMethodError) { v.mv2 }
+ assert_raise(NoMethodError) { v.mv3 }
+
+ assert_nothing_raised { v.__send__(:mv1) }
+ assert_nothing_raised { v.__send__(:mv2) }
+ assert_nothing_raised { v.__send__(:mv3) }
+
+ assert_nothing_raised { v.instance_eval { mv1 } }
+ assert_nothing_raised { v.instance_eval { mv2 } }
+ assert_nothing_raised { v.instance_eval { mv3 } }
+ end
end
diff --git a/vm_method.c b/vm_method.c
index 50f0b12e5a..becce27c1c 100644
--- a/vm_method.c
+++ b/vm_method.c
@@ -566,8 +566,9 @@ rb_method_boundp(VALUE klass, ID id, int ex)
rb_method_entry_t *me = rb_method_entry(klass, id);
if (me != 0) {
- if ((ex & ~NOEX_RESPONDS) && (me->flag & NOEX_PRIVATE)) {
- return FALSE;
+ if ((ex & NOEX_RESPONDS) && (me->flag & NOEX_PROTECTED) ||
+ (ex & ~NOEX_RESPONDS) && (me->flag & NOEX_PRIVATE)) {
+ return 0;
}
if (!me->def) return 0;
if (me->def->type == VM_METHOD_TYPE_NOTIMPLEMENTED) {