Return statements in blocks (19/19)


#1

Hi,

I was trying to sort the array of fruit names in reverse alphabetical order by using if/elsif/else statements in a block rather than the <=> operator in a block. I am aware that in the block that I am passing to the .sort! method, I need to compare two elements and return a -1, 0, or 1 (first > second, first = second, first < second, respectively in this problem). This was my initial code that gave me errors:

fruits = ["orange", "apple", "banana", "pear", "grapes"]

fruits.sort! do |firstFruit, secondFruit|
    if firstFruit ==  secondFruit
        return 0
    elsif firstFruit >  secondFruit
        return -1
    else
        return 1
    end
end

However, I was tinkering around with my code and when I changed it to the following, everything worked as it should:

fruits = ["orange", "apple", "banana", "pear", "grapes"]`

fruits.sort! do |firstFruit, secondFruit|
    if firstFruit ==  secondFruit
        0
    elsif firstFruit >  secondFruit
        -1
    else
        1
    end
end

The only thing I did differently was omitting the return statements in the if/elsif/else branch. So my question is this: why did the return statements cause this program to not work?


#2

This is kind of a guess because I don't know the inner workings of how the sort! method works, but here goes:

When you explicitly return a value, it breaks out of the method as soon as it hits a true case. If firstFruit == secondFruit, the block will return 0 and the rest of the block won't be run.

Implicit returns (where 0, -1, or 1 are getting returned without explicitly using a return statement) will let Ruby run over the whole block, even after the first true condition is met.

Explicit returns should be fine if sort! worked like a regular loop, but my guess is that it's not working quite like a normal loop and breaking out of the conditions early is what's causing errors.


#3

In Ruby, the last statement is always the return statement, and in this case there is only one statement which should be the return statement anyway, so I think the only reason why the two versions would behave differently is due to the test codes written by the developers.


#4

Thank you @katlandreth and @laushinka for your replies. Yes, it seems that I called an explicit return when an implicit return should be used, and that seems to have caused problems for my first snippet of code.