Respond_to?(<protected method name>) returns true

 今さらかもしれませんが、 respond_to? で protected メソッドを
検査すると真になるのってそういうものでしたっけ。

 respond_to? を使う目的を考えると釈然としないのですが、この
挙動は意図的でしょうか。

% cat test.rb
class X
def foo
p :foo
end
protected :foo
end

x = X.new

respond_to? で事前にテストするとtrue

p x.respond_to?(:foo)
#=> true

でも実際に呼ぶとNoMethodError

x.foo
#=> protected method `foo’ called for #<X:0x00000100861ae0>
(NoMethodError)

e$B$^$D$b$He(B e$B$f$-$R$m$G$9e(B

In message “Re: [ruby-dev:40461] respond_to?()
returns true”
on Mon, 22 Feb 2010 23:49:37 +0900, “Akinori MUSHA”
[email protected] writes:

|e$B!!:#$5$i$+$b$7$l$^$;$s$,!"e(B respond_to? e$B$Ge(B protected e$B%a%=%C%I$re(B
|e$B8!::$9$k$H??$K$J$k$N$C$F$=$&$$$&$b$N$G$7$?$C$1!#e(B

protectede$B%a%=%C%I$O%l%7!<%P$K$h$C$F8F$Y$k$+8F$Y$J$$$+7h$^$k$Ne(B
e$B$G!"%l%7!<%P>pJs$re(B(e$BDL>o$NJ}K!$G$Oe(B)e$B;}$?$J$$e(B respond_to?
e$B$G$Oe(B
e$B!V8F$Y$k$+$b$7$l$J$$!W$H$7$F??$rJV$7$F$$$^$9!#e(B

|e$B!!e(Brespond_to? e$B$r;H$&L\E*$r9M$($k$H<aA3$H$7$J$$$N$G$9$,!"$3$Ne(B
|e$B5sF0$O0U?^E*$G$7$g$&$+!#e(B

e$B$=$&$$$&0UL#$G$O0U?^E*$G$9!#?<$/9M;!$7$?$o$1$G$O$"$j$^$;$s$,!#e(B

e$B8F$Y$k;~$@$1$Ke(Brespond_to?e$B$O??$rJV$9$Y$-$G$“$k!”$H9M$($k$H!“%3!<e(B
e$B%k%U%l!<%`$rAv::$7$F!”%l%7!<%P>pJs$r<h$j=P$9I,MW$,$"$j$^$9!#e(B
e$B$H$9$k$H!“e(Bsende$B7PM3$G8F$S=P$5$l$?;~$K$O$I$&$9$k$+!”$J$I9M$($ke(B
e$B$H$I$s$I$sJ#;(2=$7$=$&$G$9!#e(B

e$B$7$+$7!":#!"2~$a$F9M$($k$H!"e(Bmethod_missinge$B$G<B8=$5$l$k%a%=%Ce(B
e$B%I$G$O!“8F$S=P$9$3$H$,$G$-$F$be(B respond_to?
e$B$O56$rJV$9$o$1$G$9e(B
e$B$+$i!”$3$l$O!V8F$Y$J$$$+$b$7$l$J$$$b$N$O56!W$H$$$&%k!<%k$G$"e(B
e$B$k$H8+$J$9$3$H$,$G$-$^$9!#$3$3$+$i$NN`?d$+$i$$$($Pe(B protected
e$B$J%a%=%C%I$KBP$9$ke(Brespond_to? e$B$O56$rJV$9$Y$-$J$N$+$b$7$l$^$;e(B
e$B$s!#e(B

e$B$I$&$7$^$7$g$&!)e(B

                            e$B$^$D$b$He(B e$B$f$-$R$me(B /:|)

At Tue, 23 Feb 2010 14:09:52 +0900,
matz wrote:

In message “Re: [ruby-dev:40461] respond_to?() returns true”
on Mon, 22 Feb 2010 23:49:37 +0900, “Akinori MUSHA” [email protected] writes:

| 今さらかもしれませんが、 respond_to? で protected メソッドを
|検査すると真になるのってそういうものでしたっけ。

protectedメソッドはレシーバによって呼べるか呼べないか決まるの
ã§ã€ãƒ¬ã‚·ãƒ¼ãƒæƒ…å ±ã‚’(通常の方法では)持たない respond_to? では
「呼べるかもしれない」として真を返しています。

 考えるに、 respond_to? で調べた上で、 protected であってもなお
呼びたいということはまれではないでしょうか。protected メソッドは
その存在を知識として共有する相互関係において呼ばれるものであり、
同族判定は必要なら通常 duck type test に先だって行いますから、
respond_to? は protected メソッドを呼べるかもしれないとして気に
する必要はないように思えます。

しかし、今、改めて考えると、method_missingで実現されるメソッ
ドでは、呼び出すことができても respond_to? は偽を返すわけです
から、これは「呼べないかもしれないものは偽」というルールであ
ると見なすことができます。ここからの類推からいえば protected
なメソッドに対するrespond_to? は偽を返すべきなのかもしれませ
ん。

どうしましょう?

 もう一つ、 instance コンテキストで private メソッドについて
respond_to? を呼んでも偽になります。

class X
def foo
p :foo
end
private :foo

def bar
# 事前に調べると偽
p respond_to?(:foo)

# でも呼べる
foo

end
end

X.new.bar

 このように respond_to? では、呼べるかどうかの検査という視点に
おいて偽陽性と偽陰性がともに生じています。NoMethodError は気軽に
rescue すべき例外ではなく(呼んだメソッドの先のバグも拾ってしまう)、
それを避けるための respond_to? ですから、少なくとも呼ぶこと自体は
エラーにならないときのみ真を返すようにし、偽陽性を排除した方がいい
のではないかと考えます。

 ところで、この問題に気づいたのは OpenStruct をいじっていたときの
ことです。同クラスには table という名前の protected メソッドがある
にも関わらず、同じ名前のプロパティを使っても誤動作しなかったのです。

 そのからくりはこうでした。未知のプロパティにアクセスされると、
method_missing は必要に応じて getter/setter を定義するのですが、
その「必要性」の検査は respond_to? で行っています。ここでたまたま
respond_to?(:table) が真になるため、 obj.table = 1 としても getter
メソッド table は(再)定義されません。従ってサブクラス等で protected
メソッド table を使っていても問題ありません。一方、 obj.table と
値を取得しようとするときは protected メソッドの呼び出しは無効なので
method_missing にルートされ、見事に値を得ることができるわけです。

 本当は偶然ではないのかもしれませんが、特殊な例であることは確か
なので、 method(key).owner から判定するような作りに直すことはでき
ます(すでに手元にあります)。

 respond_to? の仕様を変更するとこのような非互換性も生じますが、
呼べないものが真を返さなくなることは概して歓迎できるのではないかと
思います。何か見落としはあるでしょうか。

At Wed, 24 Feb 2010 00:55:39 +0900,
matz wrote:

排除についてですが、ちょっと考えた結果、賛成します。
 ご検討ありがとうございます。賛成くださるのは偽陽性の排除ですよね。

 偽陰性の方は、ちょっと私のニュアンスがよくなかったですが、仕様と
して受け入れています。両側がぶれるのはよろしくないので揃えるべき
方だけでも揃えましょうという提案でした。

| respond_to? の仕様を変更するとこのような非互換性も生じますが、
|呼べないものが真を返さなくなることは概して歓迎できるのではないかと
|思います。何か見落としはあるでしょうか。

私は思いつかないのですが、どなたか気がつきますでしょうか。
移行プロセスにはリリースマネージャに一任します。

 私は広義にはバグといってもいいような気がしますし、 grep しても
protected ãƒ¡ã‚½ãƒƒãƒ‰ã®ä½¿ç”¨é »åº¦ã¯ã•ã»ã©å¤šããªã„ã®ã§å¤§ããªå•é¡Œã«ã¯
ならないと推測します。とはいえ 1.8 は変更せずそのままとします。

e$B$^$D$b$He(B e$B$f$-$R$m$G$9e(B

In message “Re: [ruby-dev:40465] Re: respond_to?() returns true”
on Wed, 24 Feb 2010 01:12:55 +0900, “Akinori MUSHA”
[email protected] writes:

|> e$BA0$N%a!<%k$G$b=q$$$?$h$&$Ke(B method_missing e$B$K$h$k561"@-$OB8:_e(B
|> e$B$9$k$N$G!“K<AE*$K$O;XE&$OEv$?$C$F$$$k$N$G$9$,!#$G!“561”@-$Ne(B
|> e$BGS=|$K$D$$$F$G$9$,!”$A$g$C$H9M$($?7k2L!“;?@.$7$^$9!#e(B
|
|e$B!!$48!F$$”$j$,$H$&$4$6$$$^$9!#;?@.$/$@$5$k$N$O56M[@-$NGS=|$G$9$h$M!#e(B

e$B$“!”$=$&$G$9!#e(Bprotectede$B$KBP$7$Fe(Brespond_to?e$B$,??$rJV$7$F$$$k$Ne(B
e$B$r56$KE}0l$9$k$H$$$&$3$H$G$9$M!#e(B

Hi!

Has a decision been made on this?

For the record, I also feel that respond_to? should return false for
protected methods.

I feel that with the introduction of respond_to_missing?, it would be
a great time to specify explicitely what happens for protected
methods.

Marc-André

2010/2/23 Yukihiro M. [email protected]:

At Wed, 24 Feb 2010 01:25:45 +0900,
matz wrote:

を偽に統一するということですね。
 だいぶ間が空いてしまいましたが、これでどうでしょうか。

Index: vm_method.c

— vm_method.c (revision 28446)
+++ vm_method.c (working copy)
@@ -566,8 +566,9 @@ rb_method_boundp(VALUE klass, ID id, int
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) {
    Index: test/ruby/test_method.rb
    ===================================================================
    — test/ruby/test_method.rb (revision 28446)
    +++ test/ruby/test_method.rb (working copy)
    @@ -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

e$B$^$D$b$He(B e$B$f$-$R$m$G$9e(B

In message “Re: [ruby-dev:40463] Re: respond_to?() returns true”
on Tue, 23 Feb 2010 23:46:51 +0900, “Akinori MUSHA”
[email protected] writes:

|e$B!!$b$&0l$D!"e(B instance e$B%3%s%F%-%9%H$Ge(B private e$B%a%=%C%I$K$D$$$Fe(B
|respond_to? e$B$r8F$s$G$b56$K$J$j$^$9!#e(B

e$B$3$l$O;EMM$G$9!#$^$:!"86B’$H$7$F!"e(Binstancee$B%3%s%F%-%9%H8F$S=Pe(B
e$B$7$5$l$?$+$I$&$+$r%a%=%C%I$N<BAuB&$,CN$k$3$H$O:$Fq$G$9$+$i!“e(B
respond_to? e$B$O!”$=$l$KBP$9$kBP1~$O9T$$$^$;$s!#$h$C$F!"e(B

self.respond_to?(:foo)

e$B$He(B

respond_to?(:foo)

e$B$N0UL#$OF1$8$G$9!#$=$7$F!"e(Brespond_to? e$B$Oe(B private
e$B$J$b$N$r4^e(B
e$B$`$+$I$&$+$O!"BhFs0z?t$G;XDj$7$^$9!#e(Btruee$B$,;XDj$5$l$?;~$O!"e(B
privatee$B$r4^$_$^$9!#e(B

|e$B!!$3$N$h$&$Ke(B respond_to? e$B$G$O!“8F$Y$k$+$I$&$+$N8!::$H$$$&;kE@$Ke(B
|e$B$*$$$F56M[@-$H561”@-$,$H$b$K@8$8$F$$$^$9!#e(BNoMethodError e$B$O5$7Z$Ke(B
|rescue e$B$9$Y$-Nc30$G$O$J$/e(B(e$B8F$s$@%a%=%C%I$N@h$N%P%0$b=&$C$F$7$^$&e(B)e$B!“e(B
|e$B$=$l$rHr$1$k$?$a$Ne(B respond_to? e$B$G$9$+$i!”>/$J$/$H$b8F$V$3$H<+BN$Oe(B
|e$B%(%i!<$K$J$i$J$$$H$-$N$_??$rJV$9$h$&$K$7!"56M[@-$rGS=|$7$?J}$,$$$$e(B
|e$B$N$G$O$J$$$+$H9M$($^$9!#e(B

e$B$H$$$&$o$1$G!“e(Bprivatee$B$N7o$O561”@-$G$O$J$$$H9M$($^$9!#$?$@$7!“e(B
e$BA0$N%a!<%k$G$b=q$$$?$h$&$Ke(B method_missing e$B$K$h$k561”@-$OB8:_e(B
e$B$9$k$N$G!“K<AE*$K$O;XE&$OEv$?$C$F$$$k$N$G$9$,!#$G!“561”@-$Ne(B
e$BGS=|$K$D$$$F$G$9$,!”$A$g$C$H9M$($?7k2L!";?@.$7$^$9!#e(B

|e$B!!e(Brespond_to? e$B$N;EMM$rJQ99$9$k$H$3$N$h$&$JHs8_49@-$b@8$8$^$9$,!“e(B
|e$B8F$Y$J$$$b$N$,??$rJV$5$J$/$J$k$3$H$O35$7$F4?7^$G$-$k$N$G$O$J$$$+$He(B
|e$B;W$$$^$9!#2?$+8+Mn$H$7$O$”$k$G$7$g$&$+!#e(B

e$B;d$O;W$$$D$+$J$$$N$G$9$,!"$I$J$?$+5$$,$D$-$^$9$G$7$g$&$+!#e(B
e$B0\9T%W%m%;%9$K$O%j%j!<%9%^%M!<%8%c$K0lG$$7$^$9!#e(B

                            e$B$^$D$b$He(B e$B$f$-$R$me(B /:|)

e$B1sF#$G$9!#e(B

2010e$BG/e(B6e$B7ne(B27e$BF|e(B0:09 Akinori MUSHA [email protected]:

e$B$“!”$=$&$G$9!#e(Bprotectede$B$KBP$7$Fe(Brespond_to?e$B$,??$rJV$7$F$$$k$Ne(B
e$B$r56$KE}0l$9$k$H$$$&$3$H$G$9$M!#e(B

e$B!!$@$$$V4V$,6u$$$F$7$^$$$^$7$?$,!"$3$l$G$I$&$G$7$g$&$+!#e(B

e$B$3$l$K$h$C$Fe(B rubyspec
e$B$,0J2<$N$h$&$K%(%i!<$r=P$9$h$&$K$J$j$^$7$?!#e(B

marc-andre e$B$,D>$7$F$/$l$k$+$J$"e(B

Kernel#respond_to_missing? isn’t called when obj responds to the given
protected method FAILED
Expected false to be true
/home/mame/work/ruby/spec/rubyspec/core/kernel/respond_to_missing_spec.rb:65:in
block (3 levels) in <top (required)>' /home/mame/work/ruby/spec/rubyspec/core/kernel/respond_to_missing_spec.rb:5:in block in <top (required)>’
/home/mame/work/ruby/spec/rubyspec/core/kernel/respond_to_missing_spec.rb:4:in
`<top (required)>’

An exception occurred during: Mock.verify_count
Kernel#respond_to_missing? isn’t called when obj responds to the given
protected method FAILED
Mock ‘#KernelSpecs::A:0x859f65c’ expected to receive
‘respond_to_missing?’ exactly 0 times
but received it 1 times
/home/mame/work/ruby/spec/rubyspec/core/kernel/respond_to_missing_spec.rb:5:in
block in <top (required)>' /home/mame/work/ruby/spec/rubyspec/core/kernel/respond_to_missing_spec.rb:4:in <top (required)>’

Kernel#respond_to_missing? isn’t called when obj responds to the given
protected method, include_private = true FAILED
Expected false to be true
/home/mame/work/ruby/spec/rubyspec/core/kernel/respond_to_missing_spec.rb:70:in
block (3 levels) in <top (required)>' /home/mame/work/ruby/spec/rubyspec/core/kernel/respond_to_missing_spec.rb:5:in block in <top (required)>’
/home/mame/work/ruby/spec/rubyspec/core/kernel/respond_to_missing_spec.rb:4:in
`<top (required)>’

An exception occurred during: Mock.verify_count
Kernel#respond_to_missing? isn’t called when obj responds to the given
protected method, include_private = true FAILED
Mock ‘#KernelSpecs::A:0x8224f90’ expected to receive
‘respond_to_missing?’ exactly 0 times
but received it 1 times
/home/mame/work/ruby/spec/rubyspec/core/kernel/respond_to_missing_spec.rb:5:in
block in <top (required)>' /home/mame/work/ruby/spec/rubyspec/core/kernel/respond_to_missing_spec.rb:4:in <top (required)>’

Kernel#respond_to? returns true if obj responds to the given protected
method FAILED
Expected false
to equal true

/home/mame/work/ruby/spec/rubyspec/core/kernel/respond_to_spec.rb:30:in
block (2 levels) in <top (required)>' /home/mame/work/ruby/spec/rubyspec/core/kernel/respond_to_spec.rb:12:in <top (required)>’

Kernel#respond_to? returns true if obj responds to the given protected
method, include_private = true FAILED
Expected false
to equal true

/home/mame/work/ruby/spec/rubyspec/core/kernel/respond_to_spec.rb:36:in
block (2 levels) in <top (required)>' /home/mame/work/ruby/spec/rubyspec/core/kernel/respond_to_spec.rb:12:in <top (required)>’

Kernel#respond_to? returns true if obj responds to the given protected
method FAILED
Expected false
to equal true

/home/mame/work/ruby/spec/rubyspec/core/kernel/respond_to_spec.rb:42:in
block (2 levels) in <top (required)>' /home/mame/work/ruby/spec/rubyspec/core/kernel/respond_to_spec.rb:12:in <top (required)>’

Delegator#method returns a method object for protected methods of the
delegate object ERROR
NameError: undefined method prot' for class DelegateSpecs::Delegator’
/home/mame/work/ruby/spec/rubyspec/library/delegate/delegator/method_spec.rb:17:in
method' /home/mame/work/ruby/spec/rubyspec/library/delegate/delegator/method_spec.rb:17:in block (2 levels) in <top (required)>’
/home/mame/work/ruby/spec/rubyspec/library/delegate/delegator/method_spec.rb:4:in
`<top (required)>’

SimpleDelegator.new forwards protected method calls ERROR
NoMethodError: undefined method prot' for #<DelegateSpecs::Simple:0xf73daac> /home/mame/work/ruby/spec/rubyspec/library/delegate/delegator/send_spec.rb:15:in block (2 levels) in <top (required)>’
/home/mame/work/ruby/spec/rubyspec/library/delegate/delegator/send_spec.rb:4:in
`<top (required)>’

Hi!

Can I conclude by r28543 and the unclear google translation below that
the change for respond_to? has been accepted? If so I will gladly
adapt the specs for 1.9.3+

Thanks

Marc-André

2010/7/5 Yukihiro M. [email protected]:
|>> Oh, yes. protected against respond_to? that returns true
|>> It is that a false unity.
|>
|> I have a vacant lot between, what about this.

I do not think good.

| Rubyspec This now gives an error like the following.
| # Marc-andre Maybe it will fix it

I’m sure will again.

e$B$^$D$b$He(B e$B$f$-$R$m$G$9e(B

In message “Re: [ruby-dev:41820] Re: respond_to?() returns true”
on Tue, 6 Jul 2010 00:28:07 +0900, Yusuke ENDOH [email protected]
writes:

|>> e$B$“!”$=$&$G$9!#e(Bprotectede$B$KBP$7$Fe(Brespond_to?e$B$,??$rJV$7$F$$$k$Ne(B
|>> e$B$r56$KE}0l$9$k$H$$$&$3$H$G$9$M!#e(B
|>
|> e$B!!$@$$$V4V$,6u$$$F$7$^$$$^$7$?$,!"$3$l$G$I$&$G$7$g$&$+!#e(B

e$B$$$$$s$8$c$J$$$G$7$g$&$+!#e(B

|e$B$3$l$K$h$C$Fe(B rubyspec e$B$,0J2<$N$h$&$K%(%i!<$r=P$9$h$&$K$J$j$^$7$?!#e(B
|# marc-andre e$B$,D>$7$F$/$l$k$+$J$"e(B

e$B$-$C$HD>$7$F$/$l$^$9$h!#e(B

Hi,

In message “Re: [ruby-dev:41824] Re: respond_to?() returns true”
on Tue, 6 Jul 2010 13:31:28 +0900, Marc-Andre L.
[email protected] writes:

|Can I conclude by r28543 and the unclear google translation below that
|the change for respond_to? has been accepted? If so I will gladly
|adapt the specs for 1.9.3+

It’s accepted. Some RubySpec test failures are caused by this
change. We should fix them after the change is checked in. Will you?

          matz.

Hi,

On Tue, Jul 6, 2010 at 1:23 AM, Yukihiro M. [email protected]
wrote:

It’s accepted.

Great.

Some RubySpec test failures are caused by this
change. We should fix them after the change is checked in. Will you?

Yes (done for the most part).

Looking more closely at the change, it is not what I expected.

class C
protected
def is_protected; end
end

C.new.respond_to?(:is_protected, true) # => false, I expected true

I feel that either C.new.respond_to?(:is_protected, true) should
return true, or else there should be another way to ask if a method
respond_to a protected method, say like
C.new.respond_to?(:is_protected, :any)

Here’s a patch for the first option.

diff --git a/vm_method.c b/vm_method.c
index becce27…ea4afe4 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_PROTECTED) ||
    
  •       (ex & ~NOEX_RESPONDS) && (me->flag & NOEX_PRIVATE)) {
    
  •   if ((ex & ~NOEX_RESPONDS) && (
    
  •       (me->flag & NOEX_PRIVATE) ||
    
  •       ((ex &  NOEX_RESPONDS) && (me->flag & NOEX_PROTECTED)))) {
          return 0;
      }
      if (!me->def) return 0;
    

@@ -1257,10 +1258,10 @@ rb_respond_to(VALUE obj, ID id)

/*

  • call-seq:
    • obj.respond_to?(symbol, include_private=false) -> true or false
      
    • obj.respond_to?(symbol, include_all=false) -> true or false
      
    • Returns +true+ if obj responds to the given
    • method. Private methods are included in the search only if the
    • method. Private and protected methods are included in the search
      only if the
    • optional second parameter evaluates to +true+.
    • If the method is not implemented,
      @@ -1286,7 +1287,7 @@ obj_respond_to(int argc, VALUE *argv, VALUE obj)

/*

  • call-seq:
    • obj.respond_to_missing?(symbol, include_private) -> true or 
      

false

    • obj.respond_to_missing?(symbol, include_all) -> true or false
      
    • Hook method to return whether the obj can respond to id method
    • or not.

At Wed, 7 Jul 2010 02:31:28 +0900,
Marc-Andre L. wrote:

return true, or else there should be another way to ask if a method
respond_to a protected method, say like
C.new.respond_to?(:is_protected, :any)

True. That was missing from my test cases. Thanks for point it out.

Here’s a patch for the first option.

I’ll commit it later today with some test cases.