LINUX.ORG.RU

Perl, выкрутасы. Сделать функцию наподобие shift.

 , ,


0

1

Ну вот есть в перле такая функция shift, которую если дёрнуть без аргументов берёт и сдвигает массив аргументов той функции внутри которой она была вызвана. Можно ли на перле написать функцию с подобным же поведением?

Иными словами нужно внутри функции получить ссылку/нессылку на аргументы вызывающей функции.

Можно сделать так:

sub get_caller_args (;$) {
  my $n = shift;
  $n = defined $n? $n:1;
  my $ret;
  package DB {
    my($t,$t1) = caller($n);
  };
  $ret = \@DB::args;
  return $ret;
}

Оно покажет аргументы вызывающей функции, но проблема в том, что оно никак не отреагирует, если эргументы уже были сдвинуты.

Пример:

sub test ($@) {
  my $self = shift;
  use Data::Dumper;
  print "Self: $self,\n", Dumper(get_caller_args()), "\n";
}

Ну и вызов test 1,2,3 вернет: Self: 1, $VAR1=[1,2,3], а надо так: Self: 1, $VAR1=[2,3];

★★★★

Ничего не понял, но shift по умолчанию применяется к @_, там как раз аргументы хранятся.

DELIRIUM ★★★★★ ()

оно никак не отреагирует, если эргументы уже были сдвинуты.

Я сомневаюсь что реально достать аргументы после сдвига, perl вряд ли будет их копировать еще куда то.

А ло сдвига нельзя вызывать эту функцию? Какая в целом задача? Может можно написать обёртку?

disarmer ★★★ ()

есть в перле такая функция
Можно ли на перле написать

Это засада, котаны, не ведитесь

zolden ★★★★★ ()
Ответ на: комментарий от DELIRIUM

shift по умолчанию применяется к @_, там как раз аргументы хранятся.

угу. Вот и надо написать такую же функцию, которая по умолчанию будет применяться к @_.

Bad_ptr ★★★★ ()
Ответ на: комментарий от disarmer

Я сомневаюсь что реально достать аргументы после сдвига, perl вряд ли будет их копировать еще куда то.

но shift, то их как-то достаёт. shiftить можно ведь несколько раз. Или это уже надо через потроха интерпретатора как-то подлезать с сишечкой.

А ло сдвига нельзя вызывать эту функцию?

можно, но должно быть можно и после.

Какая в целом задача? Может можно написать обёртку?

можно. Но задача чисто абстрактная — удобство, т.к. функция часто вызывается my_func @_, чтобы не писать постоянно это @_.

Bad_ptr ★★★★ ()
Ответ на: комментарий от Bad_ptr

но shift, то их как-то достаёт.

shift удаляет нулевой элемент массива и возвращает его. После этого этот элемент повторно уже не достать, больше этот массив нигде не хранится

shiftить можно ведь несколько раз.

Если в массиве несколько элементов, то да, но один и тот же элемент он не вернёт.

функция часто вызывается my_func @_, чтобы не писать постоянно это @_.

Вообще то если ничего не передать функции, по дефолту как раз передастся @_. Так что можно писать просто &my_func.

% perl -wE 'sub f{say @_};@_=(1,2,3);&f'
123

disarmer ★★★ ()
Ответ на: комментарий от disarmer

Вообще то если ничего не передать функции, по дефолту как раз передастся @_. Так что можно писать просто &my_func.

Ну да, ты прав :D. Хотя это работает только если перед функцией ставить &, без этого — фиг. //но тоже вариант, да

Bad_ptr ★★★★ ()
Последнее исправление: Bad_ptr (всего исправлений: 1)

А что мешает передавать аргументы «родителя» в твою get_caller_args в качестве массива? По моему ты страдаешь полной фигнёй.
Или я просто нифига не понял, что ты хочешь.

nexfwall ★★★★ ()
Последнее исправление: nexfwall (всего исправлений: 1)
Ответ на: комментарий от nexfwall

А что мешает передавать аргументы

ничего, так и делал, теперь буду через & вызывать, поскольку такой вызов ещё и производительнее получается(хотя и не на много), в случае если тебе надо тупо передать @_.

По моему ты страдаешь полной фигнёй.

все там будем

я просто нифига не понял, что ты хочешь

ну удобно же, когда shift вызываешь без аргументов, вот и для своих функций так хочется.

Bad_ptr ★★★★ ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.