Why is else without rescue useless with statement modifiers?

def sane?
sane = “true” if “a” == “a” else sane = “false”
end

puts sane?

=>warning: else without rescue is useless
=>false

vs

def sane?
if “a” == “a” then sane = true else sane = “false”
end
end

puts sane?

=>true

The first definition simply isn’t correct. If you want to use the “if”
modifier, you cannot attach an “else” statement:

if

Ruby does recognize the “else”, but it thinks it belongs to the error
handling of the method:

def sane?
sane = true if “a” == “a”
rescue …

else # no exception raised
sane = “false”
end

Note that the “sane” variable again doesn’t make sense, because you’re
aren’t using it. Leave it out:

def sane?
if “a” == “a” then “true” else “false” end
end

You might also use the ternary operator:

def sane?
“a” == “a” ? “true” : “false”
end

or directly return the result of the comparison:

def sane?
“a” == “a”
end

This will, however, return a boolean instead of a string.

On Fri, May 18, 2012 at 07:36:06AM +0900, Jan E. wrote:

or directly return the result of the comparison:

def sane?
“a” == “a”
end

This will, however, return a boolean instead of a string.

This works if you want a string:

def sane?
    ('a' == 'a').to_s
end

On Fri, May 18, 2012 at 06:25:19AM +0900, roob noob wrote:

def sane?
sane = “true” if “a” == “a” else sane = “false”
end

puts sane?

=>warning: else without rescue is useless
=>false

Others have touched on this, but for more detail, I’ll try to explain.

You are using an inline “if” here:

(do something) if (condition)

That usage of “if” does not accpet an “else”. If you want to have an
“else” clause with your if, you need to test the condition first. One
form is, of course, the other example you provided:

def sane?
if “a” == “a” then sane = true else sane = “false”
end
end

puts sane?

=>true

. . . except that the assignments to the “sane” variable is meaningless
here. What you probably want is either this:

def sane?
  if 'a' == 'a' then true else false end
end

. . . or this (which is a bit clearer, in my opinion):

def sane?
  if 'a' == 'a'
    true
  else
    false
  end

As mentioned by others, you could use a ternary operator:

def sane?
  'a' == 'a' ? true : false
end

. . . or just directly return the result of the comparison:

def sane?
  'a' == 'a'
end

It’s also worth noting that your first example returns strings of “true”
and “false”, while your next example (as well as all of my alternatives
to it) returns the true and false boolean values themselves.

Finally, the reason it is complaining about an absent “rescue” is simply
that it has no idea what your “else” is supposed to be doing in the
first
example, because that form of an “if” conditional does not accept an
“else” condition. As such, your Ruby implementation is guessing at what
you meant the “else” to do. It happens to be guessing incorrectly in
this case.

If you do not wrap your conditional expression in a method, however, you
should get a different error message, as shown in my irb test:

>> true if 'a' == 'a' else false
SyntaxError: (irb):2: syntax error, unexpected keyword_else, 

expecting $end
true if ‘a’ == ‘a’ else false

I hope that helps.

thanks for the help :slight_smile: