Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

Ruby Ruby Booleans Build a Simple Todo List Program Part 5: Marking Todo Items Complete

Gavin Ralston
Gavin Ralston
28,770 Points

(Ruby Dev Perspective Request) Implicit returns and readability/maintainability

So in another post on this video a few weeks back, the following code was posted:

def mark_complete(name) # this is a method of the todo list
    if index = find_index(name)
      todo_items[index].mark_complete!  #this is a different item method
      return true
    else
      return false
    end
  end

Anyway, the following code should work just fine, since mark_complete! returns true or false depending on its success:

def mark_complete(name)
  if index = todo_items.index(name)
    todo_items[index].mark_complete!
  end
end

My question is: Is this me succumbing to the allure of making tinier, semi-clever, implicit code where being explicit would be a benefit to anyone who ever had to look at it?

3 Answers

Brandon Barrette
Brandon Barrette
20,485 Points

Here's my two cents:

This method would likely be called in a callback, so you'd want to return true or false, if you return false, the later callbacks are canceled (Something you'd want in a before_save for example). If you return nil, the callback will still execute. So the callback could actually not do what you want, but since you didn't return false, it still executed.

You can read more here: http://www.informit.com/articles/article.aspx?p=2220311&seqNum=2

Gavin Ralston
Gavin Ralston
28,770 Points

NOW I got it. :) Thanks for the link. I would not have expected that behavior since Ruby treats it as false, and if I tried to get too clever as I got more comfortable with Rails, that would have been an immense headache.

Brandon Barrette
Brandon Barrette
20,485 Points

Yeah, I learned this the hard way too. With callbacks you have to be careful.

Brandon Barrette
Brandon Barrette
20,485 Points

Actually I think your method returns nil if the condition is not met. Depending on your use of this method, you may actually want it to return false and not just nil.

Gavin Ralston
Gavin Ralston
28,770 Points

It totally returns nil, but that's false enough I think. I'm expecting a boolean back from this method in any case. That being said, IS being more explicit in a case like this the convention/good practice, or is this fine?

In Ruby and Rails I see a lot of implied things, like hashes without braces being passed to functions without parens, etc. I'm just not sure if something like above is going too far.

Maybe pinging the mighty Jason Seifer will bring enlightenment?

Brandon Barrette
Brandon Barrette
20,485 Points

It really depends the purpose you are using it for. Because in rails, calling associations like this could return nil as well, which can cause many errors when you try to call methods on nil. You often see the error "Can't call method on nil:NilClass"

Gavin Ralston
Gavin Ralston
28,770 Points

Perhaps there's an instance where I'd want to call a method on the true or false objects, but I just don't know why or when this would be effective yet.

I get what you're saying, but would there ever really be a time I'd want anything other than the traditional "true if success" / "false if failure"? I mean, excluding cases where I'd want to throw exceptions.

Gavin Ralston
Gavin Ralston
28,770 Points

To be clear: My own inclination is to have an explicit return of false there. I'm just asking the question becuase knowledge. :)

Daniel Silva
Daniel Silva
4,291 Points

In this case, if you'd want to return a boolean, this works in ruby:

!!nil == false #this expression is true

So, in this method you can do this:

def mark_complete(name)
  if index = todo_items.index(name)
    !!todo_items[index].mark_complete!
  end
end