4

我有一个 perl 子例程,我想将参数作为散列传递(目的是根据参数“iconsize”包含一个 css)。

我正在使用电话:

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 错误 - 在第 334 行的 CheckBar.pm 中使用“strict refs”时,不能使用字符串(“iconsize”)作为 HASH refs

我在这里做错了吗?还有其他方法可以将我的数据('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

4 回答 4

12

%{ }您正在参数列表的第一个参数上使用哈希解引用运算符 ( )。但是该参数不是哈希引用,它只是 string 'iconsize'。您可以通过以下两种方式之一做您想做的事:

传递匿名哈希引用:

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

或者继续传递一个正常的列表,就像你现在一样,并相应地改变你的函数:

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

请注意,在这个版本中,我们只是将参数列表直接分配给哈希(在提取 之后$self)。这是有效的,因为对列表name => value只是普通列表的语法糖。

我更喜欢第二种方法,因为没有特别好的理由构造一个匿名 hashref 然后立即取消引用它。

在这篇文章中还有一些关于它如何工作的好信息:面向对象的 Perl 构造函数语法

于 2010-05-26T14:42:10.370 回答
6

strict refs尝试使用该字符串iconsize作为哈希引用违反了规定。

我想你只是想要:

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

第一个参数将进入$self,其余的通过从@_.

于 2010-05-26T14:39:20.617 回答
4

将带有参数的哈希作为列表传递

您需要使用@_变量而不是shift. 像这样:

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

perl 中的哈希值和对哈希值的引用是不同的。然后你'iconsize' => '32'作为参数传递这意味着列表到 perl,它可以被解释为hash

传递带有参数的哈希作为哈希引用

但是当您尝试%{ shift || {} }perl 时,期望第二个参数是哈希引用。在这种情况下,您可以通过以下方式修复它:

get_function_bar_begin({ 'iconsize' => '32' }); ## make anonymous hash for params
于 2010-05-26T14:39:49.117 回答
1

问题是这一行:

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

正如您似乎认为的那样,这不会传递哈希引用,而是传递哈希,它以列表的形式显示给被调用者。因此,当您这样做时%{ shift },您只是在移动键'iconsize',而不是整个列表。解决方案实际上是使您的函数的第二行更简单:

my %template_params = @_;
于 2010-05-26T14:41:13.343 回答