2009/2/19 Joel VanderWerf <vjoel / path.berkeley.edu>:
> Roger Pack wrote:
>>
>> On Wed, Feb 18, 2009 at 2:35 PM, Joel VanderWerf
>> <vjoel / path.berkeley.edu> wrote:
>>>
>>> Roger Pack wrote:
>>>>>>>
>>>>>>> Then how it is different from
>>>>>>> foo.bar if foo.respond_to?(:bar)
>>>>>>>
>>>>>>> ?
>>>>>>
>>>>>> You don't have to write foo and bar twice :)
>>>>>>
>>>>>> I'm with you in thinking that adding another syntax
>>>>>> foo.?bar
>>>>>> seems a little much when a new method will do.
>>>>>> -=r
>>>>>
>>>>> Agree on both points. But what does the new method return?
>>
>> Oh I gotcha.
>> It would return  something like Yusuke Endoh's suggestion...
>> Implementation image:
>>
>>  class Object
>>   def if_not_nil
>>     self
>>   end
>>  end
>>
>>  class NilClass
>>   def if_not_nil
>>     obj = BasicObject.new
>>     def obj.method_missing(*)
>>       nil
>>     end
>>     obj
>>   end
>>  end
>>
>> not sure how the if_responds_to method would look like, exactly.
>> -=r
>
> Chaining would go like this then?
>
> x.if_not_nil.do_foo.if_not_nil.do_bar
>
> We'd have to repeat #if_not_nil at each link in the chain, and it would
> become ambiguous whether the second #if_not_nil was intended to handle
> x==nil or x.do_foo==nil (or both).
>
> Or maybe the method_missing implementation should return self? Then we could
> write:
>
> x.if_not_nil.do_foo.do_bar
>
> Then if you explicitly want to handle a nil result from do_foo, you could do
> so unambiguously:
>
> x.if_not_nil.do_foo.if_not_nil.do_bar

I think you are off the track here, at least WRT the original use of try.

The #try(:name,...) would try to call :name on the object, and return
nil (rather than an exception) when the object does not respond to the
method (or in the case of Rails it does not have the requested
attribute).

The other thing I occasionally do and which could be more streamlined
looks like this:

here fd of a pipe might be already closed but it may not

 fd.close rescue nil # hopefully prevents zombie hordes

assume Object#quiet returns an object that does not raise an exception:

 fd.quiet.close # hopefully prevent zombie hordes

Here l is non-nil but it might not contain the field:

 @src = l.scan( /src="(.*)"/)[0][0] rescue nil

Not helping here - two [] calls have to be escaped, hard to read

 @src = l.scan( /src="(.*)"/).quiet[0].quiet[0]

However, the second quiet might not be necessary since the MatchData
can be always dereferenced twice. Still not nice to read, though.

 @src = l.scan( /src="(.*)"/).quiet[0][0]

Here input might be a file or directory:

 glob = Dir.glob input + File::Separator + "*" + $IN_EXT if
(File.directory? input rescue nil)

Much simpler condition here

 glob = Dir.glob input + File::Separator + "*" + $IN_EXT if
File.quiet.directory? input



Thanks

Michal