[#54738] [ruby-trunk - Bug #8358][Open] TestSprintf#test_float test failuer on mingw32 — "phasis68 (Heesob Park)" <phasis@...>

36 messages 2013/05/02

[#54749] [ruby-trunk - Feature #8361][Open] Alternative syntax for block parameter — "alexeymuranov (Alexey Muranov)" <redmine@...>

12 messages 2013/05/02

[#54798] [ruby-trunk - Bug #8370][Open] Constants MAX_MULTIPART_LENGTH in cgi\core.rb — "xibbar (Takeyuki FUJIOKA)" <xibbar@...>

17 messages 2013/05/05

[#54850] [ruby-trunk - Feature #8377][Open] Deprecate :: for method calls in 2.1 — "charliesome (Charlie Somerville)" <charliesome@...>

27 messages 2013/05/07

[#54881] [ruby-trunk - Bug #8384][Open] Cannot build ruby against OpenSSL build with "no-ec2m" — "vo.x (Vit Ondruch)" <v.ondruch@...>

16 messages 2013/05/09

[#54921] [ruby-trunk - Bug #8393][Open] A class who's parent class is in a module can go wrong if files are required in the wrong order — "eLobato (Daniel Lobato Garcia)" <elobatocs@...>

15 messages 2013/05/12

[#54939] [ruby-trunk - Bug #8399][Open] Remove usage of RARRAY_PTR in C extensions when not needed — "dbussink (Dirkjan Bussink)" <d.bussink@...>

32 messages 2013/05/12

[#55053] [ruby-trunk - Feature #8426][Open] Implement class hierarchy method caching — "charliesome (Charlie Somerville)" <charliesome@...>

21 messages 2013/05/19

[#55096] [ruby-trunk - Feature #8430][Open] Rational number literal — "mrkn (Kenta Murata)" <muraken@...>

28 messages 2013/05/21

[#55197] [ruby-trunk - Feature #8461][Open] Easy way to disable certificate checking in XMLRPC::Client — "herwinw (Herwin Weststrate)" <herwin@...>

11 messages 2013/05/29

[ruby-core:54782] [ruby-trunk - Feature #7688] Error hiding with rb_rescue() on Comparable#==, #coerce and others

From: "Eregon (Benoit Daloze)" <redmine@...>
Date: 2013-05-04 16:24:02 UTC
List: ruby-core #54782
Issue #7688 has been updated by Eregon (Benoit Daloze).


Hello,

matz (Yukihiro Matsumoto) wrote:
> I agree with most of your changes in the patch, especially using rb_check_funcall instead of rb_rescue.
> But I personally dislike the equal operator (==) to raise error, since equal comparison is so fundamental, and most of us write code that do not expect exceptions from == operator.
> 
> Matz.

Many classes including Comparable already define #== themselves and most definitions of #== are made by the user or libraries (not using Comparable#==), so I think this rescue clause protects only few users and I believe #== methods should in any case be written to support comparison with other objects without raising an exception (unless explicitly intended).

On the other hand, if #<=> method does raise an exception, I would find it useful as it tells me I am probably comparing things I did not intend to (e.g.: objects of different classes/hierarchies). And it is more consistent with other uses of #<=> (and other definitions of #==).

Finding why my objects are never #== because I made a typo or some sensible error in #<=> might require a lot more time to debug than just seeing the exception reported in the #<=> of #==, which is straightforward to fix.

About writing code not expecting exceptions, I think most code is in this case and the fail-fast principle is great in Ruby. As #== is a method, I think it should not be treated specially even if from a mathematical or logical point of view it should never raise any exception (that being left to the programmer).
----------------------------------------
Feature #7688: Error hiding with rb_rescue() on Comparable#==, #coerce and others
https://bugs.ruby-lang.org/issues/7688#change-39125

Author: Eregon (Benoit Daloze)
Status: Open
Priority: Normal
Assignee: matz (Yukihiro Matsumoto)
Category: core
Target version: next minor


Hello,

I believe error hiding is harmful because very dangerous
(it forgets errors which is likely unexpected) and hard to debug.

But I guess the compatibility is the main reason to keep these cases.

In the cases of Comparable#== and #coerce, I believe it is not worth to be compatible with this dangerous behavior
as it will at worse help to discover bugs in #<=> and #coerce methods which would raise an exception.

I doubt anyone rely on this and the #coerce spec (see #7645) itself makes me think this is unexpected behavior.
It would also simplify the spec, and no specific #coerce behavior would be needed to be defined as it would behave as a simple method call without edge cases.

So I think rb_rescue() or rb_rescue2(..., GenericErrorClass, ...) should be avoided if possible.
I analyzed these in the code base and it is used in a couple places:
* compar.c in cmp_equal(): this is the main offender in this regard with #coerce
* numeric.c in rb_num_coerce_{cmp,relop}() which call do_coerce(,,FALSE): This is the current subject of #7645.

* io.c in io_close(): to avoid raising if #close fails, which is likely less problematic,
  although it would be nicer to rescue only IO-related errors and warn when an exception is raised.
* range.c in range_init(): this is to provide a clearer error. I think it would be nice to show the original error as well.

Removing the general rescue in cmp_equal() revealed a couple bugs in RDoc due to this problem. I guess there are many others in the wild.

Can we please remove this anti-pattern?
I believe impact is only positive and that it should be done as soon as possible.

What do you think?


-- 
http://bugs.ruby-lang.org/

In This Thread