1

I am a beginner in Ruby and I am having trouble with if else statement. As you know, Ruby will return the last calculated code if the return keyword is not specified.

Here is the issue.

  def aMethod(*args)
    if args[-1].class == String
      if args.length > 1
        args[-1]
      elsif args.length == 1
        args[-1][-1]
      end
    end
  end

The above code snippet will run correctly if I run the method with Strings as input.

p aMethod("String1", "String2") => #return "String 2"
p aMethod("String1") => return "1"

If I add another if block as shown below

    def aMethod(*args)
    if args[-1].class == String
      if args.length > 1
        args[-1]
      elsif args.length == 1
        args[-1][-1]
      end
    end
    # adding another if block
    if args[-1].class == Integer
        args[-1]
    end
    #
end

Using the same input will cause the program to return nil for both methods that accept String as an input as shown below

p aMethod("String1", "String2") => #return nil
p aMethod("String1") => # return nil
p aMethod(1,2,3,4) => # return 4

Why is this so?

2 Answers 2

3

The answer is right there in the question :) "Ruby will return the last calculated code if the return keyword is not specified".

In your first version, the last calculated code is the block in if args[-1].class == String. That block will result in nil if it evaluates to false and whatever its contents are otherwise. You can test the first version of the code with a numeric input to verify.

In your second version, the last calculated code is the block in if args[-1].class == Integer. The first block is calculated, but the result is simply lost. The two solutions would be (1) to use return explicitly, or (2) to use else if instead:

def aMethod(*args)
  if args[-1].class == String
    if args.length > 1
      args[-1]
    elsif args.length == 1
      args[-1][-1]
    end
  elsif args[-1].class == Integer
    args[-1]
  end
end

Or even better, use case:

def aMethod(*args)
  case args[-1]
  when String
    if args.length > 1
      args[-1]
    elsif args.length == 1
      args[-1][-1]
    end
  when Integer
    args[-1]
  end
end

In either case, note that any un-captured cases will return nil. For example, if your input is of a different class, or if it's a String of length 0 ('').

Sign up to request clarification or add additional context in comments.

3 Comments

Or pattern matching case args; in [*, String => a]; args.one? ? a[-1] : a; in [*,Integer => a]; a; else; nil; end
Or maybe case args; in [*, String => a] if a.one?; a[-1]; in [*, (String | Integer) => a]; a; end
I forgot you could use trailing conditionals. Although yours has a minor typo, it should be args.one?.
2

In Ruby, if is an expression, i.e. it can be evaluated and – if so – it returns a value, e.g.:

result = if true
           123
         end

result #=> 123

likewise:

result = if false
           123
         end

result #=> nil

Ruby will return the last calculated code

More specifically, it will return the result of the last expression that was evaluated. In your method, the last expression is an if and its result will become the return value.

Applied to your code, it basically works like this:

def aMethod(*args)
  result = if args[-1].class == String
             if args.length > 1
               args[-1]
             elsif args.length == 1
               args[-1][-1]
             end
           end

  return result
end

It you add another if afterwards, you have another expression which now determines the method's return value. You can think of it as every expression producing a result and the last result will become the method's return value:

def aMethod(*args)
  result = if args[-1].class == String
             if args.length > 1
               args[-1]
             elsif args.length == 1
               args[-1][-1]
             end
           end

  result = if args[-1].class == Integer
             args[-1]
           end

  return result
end

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.