0

I found this code under this question, which checks if any argument is passed to a method:

def foo(bar = (bar_set = true; :baz))
  if bar_set
    # optional argument was supplied
  end
end

What is the purpose of the ; :baz in this default value, and in what case would I use it?

2
  • Write code to print bar (and perhaps also bar_set) and then call foo first with zero arguments and then with one. Commented Aug 14, 2015 at 21:39
  • Very instructive, thank you. Commented Aug 14, 2015 at 22:09

1 Answer 1

1

The idea is that = (bar_set = true; :baz) will be evaluated only if a value is not passed to the bar parameter.

In Ruby, the return value of multiple consecutive expressions is the value of the last expression. Hence = (bar_set = true; :baz) assigns the value true to bar_set, and then sets :baz as the value for bar (because the code in the parentheses will evaluate to :baz, it being the last expression).

If a parameter was passed, bar_set will be nil and the value of bar would be whatever was given.

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

2 Comments

This is needed because whatever value you use as the default can also be passed by the caller, so it is impossible to know by looking at the value whether or not an argument was passed. But a method might want to know that. E.g., if you have a custom collection which allows very fast folding, you might want to override Enumerable#inject, but its contract is pretty complex, it basically has 4 "overloads". This is not a problem for YARV, JRuby and co, because they implement it in C or Java and thus have privileged access to the VM, but in Ruby, you need tricks like this.
:-D I just noticed that the answer which inspired this question is mine :-D

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.