Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl-Sensitive Sunglasses
 
PerlMonks  

substr odd behavior with list arguments

by wfischer (Novice)
on Mar 22, 2021 at 16:09 UTC ( #11130134=perlquestion: print w/replies, xml ) Need Help??

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

substr('abcdefg',3,2)
returns 'de' (as expected)

However,
@a = (3,2); substr('abcdefg',@a)
returns 'cdefg'

What? I mean to say, "What?"

I care because I'd like to do this: substr($string,a_subroutine_call_that_returns_offset_and_length(@some_args))

Replies are listed 'Best First'.
Re: substr odd behavior with list arguments
by choroba (Archbishop) on Mar 22, 2021 at 16:13 UTC
    That's because prototype(\&CORE::substr) is $$;$$. It means each argument is evaluated in scalar context, so in the second case @a is interpreted as scalar @a, i.e. the size of the array, which is 2.

    Use

    my ($offset, $length) = a_subroutine_call_that_returns_offset_and_leng +th(@some_args); substr('abcdefg', $offset, $length);

    map{substr$_->[0],$_->[1]||0,1}[\*||{},3],[[]],[ref qr-1,-,-1],[{}],[sub{}^*ARGV,3]
      That's the "why" -- thanks for that clear explanation. (And, yes, that's the workaround I use.)
Re: substr odd behavior with list arguments
by haukex (Bishop) on Mar 22, 2021 at 16:19 UTC
    I care because I'd like to do this: substr($string,a_subroutine_call_that_returns_offset_and_length(@some_args))

    You can get Perl to ignore the prototype (that was explained by choroba) on Perl 5.16 and up via: &CORE::substr("abcdefg",@a)

      ... And that's the "how," to make Perl act the way I want. Maybe I won't, though -- it might not be prudent to change the prototype on this low-level call. Thanks!
        it might not be prudent to change the prototype on this low-level call

        Note you're not changing it, just telling Perl to ignore it for that one call, meaning you get Perl's standard behavior of flattening the argument list. But indeed it means that you need to be certain that your subroutine will always return the offset and length; the workaround that choroba showed at least gives you the oppertunity to check that. And LanX's suggestion to wrap it in a sub is also good.

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://11130134]
Approved by choroba
Front-paged by Corion
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others cooling their heels in the Monastery: (2)
As of 2021-06-21 03:45 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?
    What does the "s" stand for in "perls"? (Whence perls)












    Results (98 votes). Check out past polls.

    Notices?