Why does adding an subsequent if-else block cause another previous if-else block to return nil?

4 weeks ago 11
ARTICLE AD BOX

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 ('').

Luis M Rodriguez-R's user avatar

3 Comments

Or pattern matching case args; in [*, String => a]; args.one? ? a[-1] : a; in [*,Integer => a]; a; else; nil; end

2025-11-06T20:08:53.163Z+00:00

Or maybe case args; in [*, String => a] if a.one?; a[-1]; in [*, (String | Integer) => a]; a; end

2025-11-08T17:39:52.163Z+00:00

I forgot you could use trailing conditionals. Although yours has a minor typo, it should be args.one?.

2025-11-08T18:12:17.983Z+00:00

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

Stefan's user avatar

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.

Read Entire Article