[LRUG] To debug the impossible bug

Murray Steele murray.steele at gmail.com
Wed Aug 3 05:41:57 PDT 2011


On 3 August 2011 12:46, Graham Ashton <graham at effectif.com> wrote:

> On 3 Aug 2011, at 12:28, Jordi Noguera Leon wrote:
>
> > I'd rather use:
> >
> > def some_other_method
> >   return foo.whatever if foo
> >   return bar.whatever if bar
> >   "some message"
> > end
>
> I don't want to pick on this specifically Jordi, but it raises an
> interesting issue.
>
> I like to replace methods like that with a sequence of if/elsif/else.
> Putting the conditional statements at the beginning makes the conditional
> logic clearer, and doesn't require the reader's familiarity with a more
> esoteric idiom.
>
> I did this very refactoring just yesterday and found a bug while I was
> doing it. The bug hadn't been visible when the code after "if" was off to
> the right of the screen.
>
> Tom Christiansen wrote about an interesting approach to the relative merits
> of "foo if bar" versus "foo && bar" in the Camel book (Programming Perl). To
> paraphrase, he argued that you should put the most significant part of the
> statement first, where "significant" means it'll help your understanding of
> what the code is doing. As I interpret it, "if foo" is more important than
> "return foo.whatever" in the example above (in which control flow is of
> primary importance).
>
> Hopefully this is making sense...
>
> It might just be me, but it seems as though the Ruby community seems to
> choose idioms that optimise for fewer lines of code, rather than for clarity
> and ease of comprehension (the two are not the same).
>

I tend to prefer "return x if y" type conditions as guard clauses at the
start of the method.  If the method truly was the example that Jordi
suggested, then yes, a clearer if/elsif/else/end structure makes more sense,
but if the "some_message" bit is actually several lines of code, then I
think the 2 guard clauses are clearer.  They say to me "get outta here ASAP
under these exceptional conditions" then the meat of the method is the
default case.

In Simon's example, I probably would stick with if/elsif/elsif/..../end
rather than guard clauses, as the method is *all* guard clause really.  That
said, now I've seen this expression-less case I might be tempted to use it
although it does seem like an unusual form that is likely to trip up people
unfamiliar with it (which seems to be most folk on this list!)

However, I might be convinced to change page_description to take an argument
and then use a traditional case along the lines of:

def page_description(for_object)
  case for_object
  when Question then for_object.background
  when User
    if for_object.bio.present?
       for_object.bio
    elsif for_object.sports.present?
       for_object.sports_list
    elsif !for_object.new_record?
       "Tribesports user: #{for_object.short_name}"
    end
  [SNIP OTHER CONDITIONS]
  when nil
    raise "LOL, WTF, ZOMG!!!!1111"
  end
end

Although this is arguably harder to parse, so maybe not.

Muz



> _______________________________________________
> Chat mailing list
> Chat at lists.lrug.org
> http://lists.lrug.org/listinfo.cgi/chat-lrug.org
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.lrug.org/pipermail/chat-lrug.org/attachments/20110803/73b4bf2e/attachment-0003.html>


More information about the Chat mailing list