Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Perl substr(STRING, @ARRAY) ne substr(STRING, OFFSET, LENGTH)?

Tags:

substr

perl

Why is this in Perl:

@x=(0,2); 
substr('abcd',@x)

evaluated as "cd"?

And this:

substr('abcd',0,2);

evaluated as "ab"?

like image 258
user1087245 Avatar asked Jan 26 '12 20:01

user1087245


2 Answers

The documented syntax of the substr operator is

substr EXPR,OFFSET,LENGTH,REPLACEMENT
substr EXPR,OFFSET,LENGTH
substr EXPR,OFFSET

not

substr EXPR,ARRAY

or the more generic

substr EXPR,LIST

This is reflected in the output of prototype (although you can't always rely on this).

$ perl -E'say prototype "CORE::substr"'
$$;$$
  • substr's 1st argument is evaluated in scalar context.
  • substr's 2nd argument is evaluated in scalar context.
  • substr's 3rd argument (optional) is evaluated in scalar context.
  • substr's 4th argument (optional) is evaluated in scalar context.

@x in scalar context is the number of elements it contains (2 in this case).

You can achieve what you want using the following:

sub mysubstr {
    if    (@_ == 2) { substr($_[0], $_[1]) }
    elsif (@_ == 3) { substr($_[0], $_[1], $_[2]) }
    elsif (@_ == 4) { substr($_[0], $_[1], $_[2], $_[3]) }
    else { die }
}

my @x = (0, 2);
mysubstr('abcd',@x)
like image 189
ikegami Avatar answered Nov 15 '22 08:11

ikegami


substr has a prototype as a built in function, so @x is not expanded is evaluated in a scalar context, which returns 2, so basically you are calling substr('abcd',scalar(@x))

like image 24
Sorin Avatar answered Nov 15 '22 08:11

Sorin