Forum: Ruby-core [Bug #2945] Regexp#=== is failed by an exception when the exception is occurred in method_missing

Posted by Kenta Murata (Guest)
on 2010-03-08 07:33
(Received via mailing list)
Bug #2945: Regexp#=== is failed by an exception when the exception is 
occurred in method_missing
http://redmine.ruby-lang.org/issues/show/2945

Author: Kenta Murata
Status: Open, Priority: Normal
Category: core, Target version: 1.9.2
ruby -v: ruby 1.9.2dev (2010-03-08 trunk 26849) [x86_64-darwin10.2.0]

When an exception is occurred in method_missing,
Regexp#=== is failed by the exception.
Is this valid behavior?

  o = Object.new
  class <<
    def method_missing(m, *args)
      raise "XXX" if m == :to_str
    end
  end
  /aaa/ === o # =:> `method_missing': XXX (RuntimeError)


If correct this, apply the following patch.

diff --git a/re.c b/re.c
index 6ec3646..8a38155 100644
--- a/re.c
+++ b/re.c
@@ -2685,6 +2685,12 @@ rb_reg_match(VALUE re, VALUE str)
     return LONG2FIX(pos);
 }

+static VALUE
+reg_check_operand(VALUE str)
+{
+    return reg_operand(str, FALSE);
+}
+
 /*
  *  call-seq:
  *     rxp === str   => true or false
@@ -2708,7 +2714,7 @@ rb_reg_eqq(VALUE re, VALUE str)
 {
     long start;

-    str = reg_operand(str, FALSE);
+    str = rb_protect(reg_check_operand, str, 0);
     if (NIL_P(str)) {
   rb_backref_set(Qnil);
   return Qfalse;
Posted by Yukihiro Matsumoto (Guest)
on 2010-03-08 07:47
(Received via mailing list)
Hi,

In message "Re: [ruby-core:28552] [Bug #2945] Regexp#=== is failed by an 
exception when the exception is occurred in method_missing"
    on Mon, 8 Mar 2010 15:32:24 +0900, Kenta Murata 
<redmine@ruby-lang.org> writes:

|When an exception is occurred in method_missing,
|Regexp#=== is failed by the exception.
|Is this valid behavior?

I think so.  What makes you think it's invalid?

              matz.
Posted by Kenta Murata (Guest)
on 2010-03-08 08:56
(Received via mailing list)
Hi,

On 2010/03/08, at 15:46, Yukihiro Matsumoto wrote:

> Hi,
> 
> In message "Re: [ruby-core:28552] [Bug #2945] Regexp#=== is failed by an exception when the exception is occurred in method_missing"
>    on Mon, 8 Mar 2010 15:32:24 +0900, Kenta Murata <redmine@ruby-lang.org> writes:
> 
> |When an exception is occurred in method_missing,
> |Regexp#=== is failed by the exception.
> |Is this valid behavior?
> 
> I think so.  What makes you think it's invalid?

I think the present behavior is unfortunate the following case.
I don't expect raising exception, but printing 2.

  o1 = Object.new
  class << o1
    def method_missing(*args)
      raise "XXX"
    end
  end

  case o1
  when /aaa/
    puts 1
  when o
    puts 2
  end
  #=> `method_missing': XXX (RuntimeError)

--
Kenta Murata
OpenPGP FP = FA26 35D7 4F98 3498 0810 E0D5 F213 966F E9EB 0BCC

E-mail: mrkn@mrkn.jp
twitter: http://twitter.com/mrkn/
blog: http://d.hatena.ne.jp/mrkn/
Posted by Yukihiro Matsumoto (Guest)
on 2010-03-08 09:13
(Received via mailing list)
Hi,

In message "Re: [ruby-core:28554] Re: [Bug #2945] Regexp#=== is failed 
by an exception when the exception is occurred in method_missing"
    on Mon, 8 Mar 2010 16:56:14 +0900, Kenta Murata <muraken@gmail.com> 
writes:

|> |Is this valid behavior?
|> 
|> I think so.  What makes you think it's invalid?
|
|I think the present behavior is unfortunate the following case.
|I don't expect raising exception, but printing 2.

I have to repeat myself.  Why do you expect so?
#method_missing raised an exception, no one captured.  Why do we
expect exceptions to be captured implicitly?


|  o1 = Object.new
|  class << o1
|    def method_missing(*args)
|      raise "XXX"
|    end
|  end
|  
|  case o1
|  when /aaa/
|    puts 1
|  when o
|    puts 2
|  end
|  #=> `method_missing': XXX (RuntimeError)
|
|--
|Kenta Murata
|OpenPGP FP = FA26 35D7 4F98 3498 0810 E0D5 F213 966F E9EB 0BCC
|
|E-mail: mrkn@mrkn.jp
|twitter: http://twitter.com/mrkn/
|blog: http://d.hatena.ne.jp/mrkn/
|
|
Posted by Kenta Murata (Guest)
on 2010-03-08 09:47
(Received via mailing list)
Hi,

On 2010/03/08, at 17:12, Yukihiro Matsumoto wrote:

> |> |Is this valid behavior?
> |> 
> |> I think so.  What makes you think it's invalid?
> |
> |I think the present behavior is unfortunate the following case.
> |I don't expect raising exception, but printing 2.
> 
> I have to repeat myself.  Why do you expect so?
> #method_missing raised an exception, no one captured.  Why do we
> expect exceptions to be captured implicitly?

Ok, I agree with you about that exceptions, no one captured,
shouldn't be captured implicitly.

But, I do still not understand Regexp#=== depends on method_missing.
I expect Regexp#=== with a non-string argument returns false.
In Regexp#===, if an argument doesn't have to_str method,
the argument is interpreted as a non-string, isn't it?
If so, Regexp#=== shouldn't raise an exception, but return false,
independently of the definition of method_missing.

> |  when o
> |    puts 2
> |  end
> |  #=> `method_missing': XXX (RuntimeError)

--
Kenta Murata
OpenPGP FP = FA26 35D7 4F98 3498 0810 E0D5 F213 966F E9EB 0BCC

本を書きました!!
『Ruby 逆引きレシピ』 
http://www.amazon.co.jp/dp/4798119881/mrkn-22

E-mail: mrkn@mrkn.jp
twitter: http://twitter.com/mrkn/
blog: http://d.hatena.ne.jp/mrkn/
Posted by Yukihiro Matsumoto (Guest)
on 2010-03-08 09:58
(Received via mailing list)
Hi,

In message "Re: [ruby-core:28556] Re: [Bug #2945] Regexp#=== is failed 
by an exception when the exception is occurred in method_missing"
    on Mon, 8 Mar 2010 17:47:26 +0900, Kenta Murata <muraken@gmail.com> 
writes:

|But, I do still not understand Regexp#=== depends on method_missing.
|I expect Regexp#=== with a non-string argument returns false.
|In Regexp#===, if an argument doesn't have to_str method,
|the argument is interpreted as a non-string, isn't it?

It's a wrong design of method_missing.  If one want exceptions from
method_missing ignored for implicit type conversion (to_str, etc.),
it should raise NoMethodError.

              matz.
Posted by Kenta Murata (Guest)
on 2010-03-08 10:25
(Received via mailing list)
Hi,

On 2010/03/08, at 17:56, Yukihiro Matsumoto wrote:

> |But, I do still not understand Regexp#=== depends on method_missing.
> |I expect Regexp#=== with a non-string argument returns false.
> |In Regexp#===, if an argument doesn't have to_str method,
> |the argument is interpreted as a non-string, isn't it?
> 
> It's a wrong design of method_missing.  If one want exceptions from
> method_missing ignored for implicit type conversion (to_str, etc.),
> it should raise NoMethodError.

I understand, I'll use NoMethodError for implicit type conversion 
methods
in method_missing.

Thanks.

--
Kenta Murata
OpenPGP FP = FA26 35D7 4F98 3498 0810 E0D5 F213 966F E9EB 0BCC

本を書きました!!
『Ruby 逆引きレシピ』 
http://www.amazon.co.jp/dp/4798119881/mrkn-22

E-mail: mrkn@mrkn.jp
twitter: http://twitter.com/mrkn/
blog: http://d.hatena.ne.jp/mrkn/
Please log in before posting. Registration is free and takes only a minute.
Existing account (Switch to SSL-encrypted connection)
NEW: Do you have a Google/GoogleMail or Yahoo account? No registration required!
Log in with Google account | Log in with Yahoo account
No account? Register here.