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?

Community
  • 1
  • 1
npresco
  • 153
  • 1
  • 2
  • 11

1 Answers1

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.

sawa
  • 165,429
  • 45
  • 277
  • 381
ndnenkov
  • 35,425
  • 9
  • 72
  • 104
  • 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. – Jörg W Mittag Aug 15 '15 at 01:53
  • :-D I just noticed that the answer which inspired this question is mine :-D – Jörg W Mittag Aug 15 '15 at 01:55