Perl substr (STRING, @ARRAY) ne substr (STRING, OFFSET, LENGTH)? - PullRequest
6 голосов
/ 27 января 2012

Почему это в Perl:

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

оценивается как "cd"?

А это:

substr('abcd',0,2);

оценивается как "ab"?

Ответы [ 3 ]

13 голосов
/ 27 января 2012

Документированный синтаксис оператора substr:

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

, а не

substr EXPR,ARRAY

или более общий

substr EXPR,LIST

Это отражено в выводе prototype (хотя вы не всегда можете на это полагаться).

$ perl -E'say prototype "CORE::substr"'
$$;$$
  • substr 1-й аргумент оцениваетсяв скалярном контексте.
  • substr 2-й аргумент оценивается в скалярном контексте.
  • substr 3-й аргумент (необязательно) оценивается в скалярном контексте.

@x в скалярном контексте - это количество элементов, которые он содержит (2 в данном случае).

Вы можете достичь желаемого, используя следующее:

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)
5 голосов
/ 27 января 2012

substr имеет прототип в качестве встроенной функции, поэтому @x не раскрывается, вычисляется в скалярном контексте, который возвращает 2, поэтому в основном вы вызываете substr ('abcd', scalar (@x))

4 голосов
/ 27 января 2012

Первый использует @x в скалярном контексте ... что означает размер @x, поэтому substr('abcd',2) дает cd.

...