1D0-437 · Question #37
Consider the following lines of code: sub mySub {( $arg,@args) = @_; foreach $val (@args) { SreturnVal .= "$arg, $val\n"; } SreturnVal."". @args; } print SmySub(1 "a value", "another value", "a…
The correct answer is A. 1, a value 1, another value 1, a parameter 1, another parameter 4. See the full explanation below for the reasoning.
Question
Consider the following lines of code:
sub mySub {( $arg,@args) = @_; foreach $val (@args) { SreturnVal .= "$arg, $val\n"; } SreturnVal."". @args; } print SmySub(1 "a value", "another value", "a parameter", "another parameter"); What is the output of these lines of code?
Options
- A1, a value 1, another value 1, a parameter 1, another parameter 4
- B1, a value 1, another value 1, a parameter 1, another parameter a value another value a parameter
- C1, a value, another value, a parameter, another parameter a value another value a parameter another
- D1, a value, another value, a parameter, another parameter 4
How the community answered
(30 responses)- A70% (21)
- B3% (1)
- C17% (5)
- D10% (3)
Community Discussion
8Flag this one as a quick win, budget 90 seconds max, and move on. The answer is A. The sub assigns the first argument to $arg (which is 1) and the rest into @args (four strings), then the foreach loop concatenates "$arg, $val" plus a newline for each element of @args, building up four lines in $returnVal. The key trick is the final expression, $returnVal . "" . @args, because the dot operator forces @args into scalar context, and in Perl scalar context an array evaluates to its element count, which is 4. So the return value is those four "1, something" lines followed by the number 4, which is exactly what option A shows.
Saw this exact question on my exam, or something very close to it, and I almost fell for D before I caught myself. The foreach loop builds up $returnVal by appending "$arg, $val\n" for each element in @args, so you get four lines of "1, a value", "1, another value", and so on, which rules out C and D right away since those have commas separating all the values instead of line breaks. The real trap is the last expression before the sub returns, $returnVal . "" . @args, because you're concatenating the array directly in scalar context, and in Perl that evaluates to the count of elements, which is 4, not the stringified contents of the array. I had a moment of doubt thinking maybe it would print the array values, but scalar context on an array is always the count, so the output ends with 4 and the answer is A.
Saw this exact one, traced @args in scalar context, picked A immediately.
Smart call on the scalar context trap, but make sure you are not burning more than 15 seconds on it because the real time sink on that topic is usually the follow-up question about wantarray behavior, which is where people stall.
I initially marked B because I read the final concatenation as interpolating the array elements, but the dot operator forces scalar context on @args, so Perl evaluates it as the element count (4) rather than the values themselves, which is spelled out in the perlop documentation under "Multiplicative Operators" and the scalar context rules for arrays. That distinction between list context and scalar context is exactly what this question is testing, and A is the only option that ends with 4.
Solid reasoning, though I'd push back slightly on framing it as "dot forces scalar context" as if dot is doing something special, because the real rule is just that any operator expecting a scalar operand will pull scalar context, and dot happens to expect strings, so the array collapses to its count before the concatenation even runs.
A is right. @args in string context evaluates to its count, 4.
That count behavior comes from scalar context, not string context specifically, and the distinction matters: perldoc perldata explains that an array in scalar context yields its element count, while an array interpolated directly inside double quotes expands its elements joined by $", so calling it "string context" can mislead someone into thinking "foo @args bar" also prints 4.