Hi --

On Thu, 22 Dec 2005, Ross Bamford wrote:

> On Thu, 22 Dec 2005 14:07:03 -0000, jwesley <justin.w.smith / gmail.com> wrote:
>
>> I disagree that this particular use of an exception would be a no-no in
>> Java.  Inability to parse input is justifiably an "exceptional" case.
>> And the handling of that exceptional case is also appropriate.
>> 
>
> Agreed, I was referring more to the idea of swapping out flow control for 
> exceptions in general. Obviously if the input is an exceptional case, throw 
> an exception. I have just been wondering about a few examples of this I've 
> seen in Ruby code, and just picked this as an 'in' to ask about it ;)
>
>> The big "no-no" about exception usage is true for any language: "Don't
>> use exceptions for flow control".
>> 
>> The following code is "wrong" for various reasons as well as violating
>> the "axiom" above:
>> 
>> begin
>>  # display 1 through 10
>>  i = 0
>>  while true
>>    unless i > 10
>>      puts i
>>    else
>>      raise "End o' the line"
>>    end
>>    i += 1
>>  end
>> rescue
>> end
>> 
>> Ruby provides enough mechanisms for "controlling the flow" that using
>> exceptions for "normal" conditions is definitely poor style, if not
>> worse.
>> 
>
> Okay, good. That was my feeling too.

I agree in general, although... there's one case where I can't resist,
at least sometimes, and that's this:

   if obj.respond_to("meth")
     obj.meth
   else
     <something else>
   end

I really dislike the repetition there, and it also technically isn't
thread-safe:

   a = Object.new
   def a.x; end

   Thread.new do
     sleep 1
     class << a; undef_method("x"); end
   end

   if a.respond_to?("x")
     sleep 2
     a.x
   end

   => undefined method `x' for #<Object:0x1cd508> (NoMethodError)

I don't know any way around it, though, except:

   begin
    obj.meth
   rescue NoMethodError
    <something else>
   end

or some variant thereof.  (Obviously in true duck-typing cases you
just send the message without this kind of check, but there are cases
where the check makes sense.)

I've toyed with the idea of some kind of special "nack" object that
would be returned on these kinds of method calls, but I don't think it
plays well with method_missing.


David

-- 
David A. Black
dblack / wobblini.net

"Ruby for Rails", from Manning Publications, coming April 2006!
http://www.manning.com/books/black