Почему Perl строго не позволяет мне передавать хэш параметров? - PullRequest
4 голосов
/ 26 мая 2010

У меня есть подпрограмма Perl, где я хотел бы передать параметры в виде хэша (цель состоит в том, чтобы включить CSS в зависимости от параметра 'iconsize').

Я использую звонок:

get_function_bar_begin('iconsize' => '32');

для подпрограммы get_function_bar_begin:

use strict;
...
sub get_function_bar_begin
{
    my $self = shift;
    my %template_params = %{ shift || {} };

    return $self->render_template('global/bars   /tmpl_incl_function_bar_begin.html',%template_params);
}

Почему это приводит к сообщению об ошибке:

Ошибка при выполнении режима запуска 'start': ошибка undef - Невозможно использовать строку ("iconsize") в качестве ссылки HASH, когда используются "строгие ссылки" на CheckBar.pm в строке 334

Я что-то здесь не так делаю? Есть ли другой способ отправить мои данные ('iconsize') в виде хэша?

(я все еще новичок в Perl)

РЕДАКТИРОВАТЬ: Решение, которое работало для меня . Я не менял звонок, но моя функция:

sub get_function_bar_begin
{
    my $self = shift;
    my $paramref = shift;
    my %params = (ref($paramref) eq 'HASH') ? %$paramref : ();
    my $iconsize = $params{'iconsize'} || '';

    return $self->render_template('global/bars/tmpl_incl_function_bar_begin.html',
        {
            'iconsize'  => $iconsize,
        }
    );
}

Ответы [ 4 ]

12 голосов
/ 26 мая 2010

Вы используете оператор хеширования (%{ }) в первом аргументе вашего списка параметров.Но этот аргумент не ссылка на хеш, это просто строка 'iconsize'.Вы можете сделать то, что вы хотите, одним из двух способов:

Передать анонимную ссылку на хэш:

get_function_bar_begin( { 'iconsize' => '32' } );

Или продолжить передавать обычный список, как вы сейчас, и изменить свойфункция соответственно:

sub get_function_bar_begin {
    my $self = shift;
    my %template_params = @_;
}

Обратите внимание, что в этой версии мы просто присваиваем список аргументов непосредственно хешу (после извлечения $self).Это работает, потому что список пар name => value является просто синтаксическим сахаром для обычного списка.

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

В этом посте также есть хорошая информация о том, как это работает: Синтаксис объектно-ориентированного конструктора Perl .

6 голосов
/ 26 мая 2010

Вы нарушаете strict refs, пытаясь использовать строку iconsize в качестве ссылки на хеш.

Я думаю, вы просто хотите:

my( $self, %template_params ) = @_;

Первый аргумент будет введен в $self, а остальные создают хеш, беря пары элементов из остальных @_.

4 голосов
/ 26 мая 2010

Передача хеша с параметрами в виде списка

Вам необходимо использовать переменную @_ вместо shift. Как это:

my %template_params = @_; ## convert key => value pairs into hash

Существует различие между хешами и ссылками на хеш в perl. Затем вы передаете 'iconsize' => '32' в качестве параметра, это означает list в perl, что можно интерпретировать как hash

Передача хеша с параметрами в качестве ссылки на хеш

Но при попытке %{ shift || {} } perl ожидает, что второй параметр будет хеш-ссылкой. В этом случае вы можете исправить это следующим образом:

get_function_bar_begin({ 'iconsize' => '32' }); ## make anonymous hash for params
1 голос
/ 26 мая 2010

Проблема в этой строке:

get_function_bar_begin('iconsize' => '32');

Это не передает хэш ссылка , как вы, кажется, думаете, но хэш, который отображается как вызываемый объект,Поэтому, когда вы делаете %{ shift }, вы просто перемещаете клавишу 'iconsize', а не весь список.Решение состоит в том, чтобы упростить вторую строку вашей функции:

my %template_params = @_;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...