dblack / wobblini.net wrote:
> 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

This has the unfortunate side effect of conflating NoMethodErrors that
are reported for other method calls besides the original obj.meth but
which occur during that method. What's the best way of handling that?
Compare exception.backtrace depth with the current backtrace depth?

It's not really threadsafe either. By the time <something else> is
executed, #meth could have been defined (though you do know it was
undefined at the time of the method call, which is an improvement over
the #respond_to version).

> 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
> 

-- 
      vjoel : Joel VanderWerf : path berkeley edu : 510 665 3407