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

You get the following warning if you use split in a scalar context to count the number of whitespace delimited tokens in a string.

$_ = 'a b c d e'; print scalar( split );; Use of implicit split to @_ is deprecated at (eval 6) line 1, <STDIN> +line 1. 5 $_ = 'a b c d e'; print $n = split;; Use of implicit split to @_ is deprecated at (eval 9) line 1, <STDIN> +line 4. 5

I understand the warning, and that it is (mostly?) inappropriate in these cases.

Shouldn't (or couldn't) this warning only be produced in a void context? Or are there scalar context cases that I haven't thought of when it is appropriate?


Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
"Science is about questioning the status quo. Questioning authority".
In the absence of evidence, opinion is indistinguishable from prejudice.
"I'd rather go naked than blow up my ass"

Replies are listed 'Best First'.
Re: More intelligent warning?
by Corion (Patriarch) on Feb 05, 2010 at 14:19 UTC

    I think the warning is still appropriate in your cases, because split modifies @_ in both cases, which I consider unfortunate :-):

    >perl -le "$_='abc';@_=qw(1 2 3);$n=split//;print for @_" a b c

    Maybe the warning should be split used in scalar context in your case, and remain as is for void context, or maybe split in non-list-context should be deprecated due to its side-effect.

      Hm That's a real "WTF were they thinking" moment :)

      Most of Perl's oddities you can squint your eyes a bit and see how and why they came about. And often, how useful they can be.

      But "I know you asked me for the count of tokens, but by the way, I've also stuck those tokens into @_ (silently overwriting your sub args!) just in case that's useful."? Nope! I can not see any rational for that.

      How long does that deprecation cycle have to last before the Guardians of the Lazy will let this be changed? :)


      Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
      "Science is about questioning the status quo. Questioning authority".
      In the absence of evidence, opinion is indistinguishable from prejudice.

        I guess it's too late for 5.12, but for 5.14, I consider it fair game. And yes, I really dislike this side effect, even though it might come in very handy while golfing or for obfuscation...

        Hm That's a real "WTF were they thinking" moment :)

        Most of Perl's oddities you can squint your eyes a bit and see how and why they came about. And often, how useful they can be.

        Indeed!

        ... wouldn't it be nice to have a no oddity pragma to deactivate all these rarely needed special features?

        Cheers Rolf

        But "I know you asked me for the count of tokens, but by the way, I've also stuck those tokens into @_ (silently overwriting your sub args!) just in case that's useful."? Nope! I can not see any rational for that.
        You're assuming split was written to easily count the number of tokens. It wasn't. It was written to split a string. Which it does. Even in void and scalar context. The fact it returns the number of tokens in scalar context is the additional feature, not its reason for existence.

        I guess the reasoning was "Hmmm, we have a function that splits a string into other strings. What can we do if there are users who call this in non-list context?" Not throwing away the result and putting in in the default list topicalizer doesn't seem that far fetched to me.

        Nope! I can not see any rational for that.

        Hmm, well. $_ is the default "this", so @_ is the default "these". If split is called implicitly on $_, it seems somewhat logical to me to implicitly split into @_.

        Bu then, the following arguably should not implicitly split into @_ :

        perl -wle '$n="";$f="abc";$n=split//,$f;print for @_'

        To defeat that behavior we have to use the "operator" with the disputed name...

        perl -wle '$n=""; $f="abc"; $n=()=split//,$f; print for @_'

        update:

        That looks like coming from looong ago. Consider:

        while(<>) { $n = split; warn "processing $n tokens\n"; &process; # implicitly takes @_ }
        So... another reminiscence of perl4. perl4!