Do or do not…
1 Mar 2008Chris came up with this excellent little snippet, try, as seen on Ruby Inside.
That inspired me to a create a similarly sugary method for an idiom I use time and again:
class Object
##
# @person.name rescue nil
# vs
# @person.do_or_do_not(:name)
def do_or_do_not(method)
send method rescue nil
end
end
##
# @person.name rescue nil
# vs
# @person.do_or_do_not(:name)
def do_or_do_not(method)
send method rescue nil
end
end







Ben, Chris from GitHub actually posted something really similar a couple of days ago:
http://ozmm.org/posts/try.html
Funny how you two arrived at nearly the same result independently.
That seems in general like a really bad idea. #try (call a method if the object responds to it) or raganwald’s #andand (call a method unless the receiver is nil) are a lot safer. With do_or_do_not you’re going to wind up swallowing any exceptions that get thrown, which will almost always lead to undesirable results or tough to track down bugs
@crayz: Best of both worlds … http://pastie.caboo.se/159850
also, programming by exception is horrible, horrible practice in general, for many of the reasons that crayz mentioned. it is also SLOW.
Well, I suppose I should add that the place where I use ‘rescue nil’ is in erb, when I want to catch the occasional non-existent relationship, and there are no bad consequences of squashing an undefined method error.
Ben – do you mean something like ’@person.employer.do_or_do_not(:name)’? Because that type of use (where there’s a potential that ‘employer’ is nil), is really better served by #andand. #do_or_do_not, the way you’ve written it, really only seems suitable for a situation where you’re doing something like UnreliableObject.do_or_do_not(:something_that_may_fail), which I really only see happening when doing some sort of periodic ping/fetch from an external service
I don’t normally run into situations where I want to run a piece of code but just not care if it raises any exceptions. I think if there’s a specific type of exception you’re trying to account for, it’s better to use a more specialized tool (like #andand) that’s less likely to have unintended consequences
crayz, yes, I did mean situations like @person.employer.name rescue nil. Somehow I had missed #andand before… I agree, that’s a better approach.
I’ve also taken to relying on #to_s, so I’d just def #to_s in Employer as self.name, and then use @person.employer in erb.
[...] Try try pattern. Useful to do stuff without checking for nil? — shared with shareomatic.com (tags: ruby) [...]
“There is no try”... Love the name, I sincerely hope installation is:
sudo gem install yoda
[...] #try, #andand, and #do_or_do_not, the one I like best (and I don’t even like any of them that much, but that’s my next [...]
[...] people behind andand, try, do_or_do_not, NilClass#method_missing, SafeNil, maybe, etc. seem to be trying to beautifully solve the problem [...]