Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

Anyone know why this is throwing the following error:
Use of implicit split to @_ is deprecated at line XXX
from the code below:
@models = map { split (/;\s*/; $_[1] ) } @models;

Replies are listed 'Best First'.
Re: deprecated split ??
by duff (Parson) on May 27, 2004 at 20:13 UTC
    Sure. You're using split in scalar context to implicitly split into @_ and that is deprecated as the message says. Just do this:
    @models = map { (split /;\s*/)[1] } @models;
    or if the inside of your map is really a little more complicated, perhaps you'd like to use a temporary array:
    @models = map { my @t = split /;\s*/; ... $t[1]; } @models;
      Since when the heck has the return value of the code inside of a map been scalar context?
      [me@host]$ perl -le 'sub x {print "yup" if wantarray} @y = map { x() } + (1,2);' yup yup [me@host]$
      Oops. I saw the darn semicolon a half-second after submitting. D'oh.
      ------------ :Wq Not an editor command: Wq
Re: deprecated split ??
by EdwardG (Vicar) on May 27, 2004 at 20:14 UTC

    Apparently because -

    Use of implicit split to @_ is deprecated (D deprecated) It makes a lot of work for the compiler when you clobber a subroutine's argument list, so it's better if you assign the results of a split() explicitly to an array (or list).

    I think this implies that when you don't specify a target array to split, @_ is used, clobbering the sub args. Must have been deprecated to avoid this happening unintentionally.

     

Re: deprecated split ??
by QM (Parson) on May 27, 2004 at 20:46 UTC
    @models = map { split (/;\s*/; $_[1] ) } @models;
    Funny, I can't get that to compile.

    Please cut and paste code - don't type it in.

    -QM
    --
    Quantum Mechanics: The dreams stuff is made of

Re: deprecated split ??
by diotalevi (Canon) on May 27, 2004 at 20:42 UTC

    There is a typo in your code. You put a semi-colon after the /;\s*/ but should have a comma instead. You also wrote $_[1] which ... I would *guess* should probably be $_->[1]. The way you've written this function and it has been interpreted is a model of obfuscation. split() called like this is in list context (contrary to someone else's assertion that it is scalar) and shouldn't pull up that warning. That perl has somehow decided to treat it as void context means that split separates the first element of the @_ array, then writes into it. The next call then splits the previous call's output and so on.

    Perhaps you mean @models = map { ( split /;\s*/ )[ 1 ] } @models which is significantly more probable.

      Nope. split is not called in list context. The fact that it's the second to last statement in the block, and not the last, makes it get called in void context.

      As a demo, runt this code:

      sub foo { printf "foo(%s) called in %s context\n", join(', ', @_), wantarray ? 'list' : defined wantarray ? 'scalar' : 'void'; } @dummy = map { foo('inside', $_); foo('last', $_) } qw(alpha beta gam +ma);
      Result:
      foo(inside, alpha) called in void context
      foo(last, alpha) called in list context
      foo(inside, beta) called in void context
      foo(last, beta) called in list context
      foo(inside, gamma) called in void context
      foo(last, gamma) called in list context
      

      Context propagation from the caller to the internal statements only happens on the last statement (for each flow), or in explicit return calls.

        split was the only expression in the block. The semicolon you thought was the statement separator was written inside the parentheses delimiting the arguments given to it.