def foo(_, _='override')
_
end
p foo("bye bye")
p foo("hello", "world")
Output:
"override"
"hello"
I could understand if the result was:
"override"
"world"
or even:
"bye bye"
"hello"
But the result I'm getting causes me confusion.
def foo(_, _='override')
_
end
p foo("bye bye")
p foo("hello", "world")
Output:
"override"
"hello"
I could understand if the result was:
"override"
"world"
or even:
"bye bye"
"hello"
But the result I'm getting causes me confusion.
Default arguments are evaluated earlier in time than regular arguments if an argument is passed for it, otherwise they are evaluated last. Almost certain but unsure how to prove it.
Meaning in this example:
at time 0 call p foo("hello", "world")
at time 1 _ = 'override'
at time 2 _ = "world"
at time 3 _ = "hello"
at time 4 variables are printed and you see "hello"
EDIT here is some evidence:
def foo(_, _='override',_)
_
end
p foo("bye bye","goodbye")
p foo("hello", "world", "three")
prints
"override"
"three"
Ican't find better explanation than this one
The reason for this is found in Ruby’s parser, in shadowing_lvar_gen. All the normal checks for duplication are skipped iff the variable name consists of exactly one underscore.
One possible explanation is that name _
stands for "unused variable". You're not supposed to even reference it, let alone expect any values of it. As it is a special name, it gets special treatment from the parser (such as suppressing "duplicate parameter" errors). I imagine that no one cared to make this code produce a logical result, because, again, these are unused variables.
If you rename it to anything else (say, a
), you'll get an error, because now this method signature doesn't make sense.