开发者

Why does Perl's strict not let me pass a parameter hash?

开发者 https://www.devze.com 2023-01-01 07:08 出处:网络
I hava开发者_Python百科 a perl subroutine where i would like to pass parameters as a hash (the aim is to include a css depending on the parameter \'iconsize\').

I hava开发者_Python百科 a perl subroutine where i would like to pass parameters as a hash (the aim is to include a css depending on the parameter 'iconsize').

I am using the call:

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

for the subroutine 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);
}

Why does this yield the error message:

Error executing run mode 'start': undef error - Can't use string ("iconsize") as a HASH ref while "strict refs" in use at CheckBar.pm at line 334

Am i doing something wrong here? Is there an other way to submit my data ('iconsize') as a hash?

(i am still new to Perl)

EDIT: Solution which worked for me. I didn't change the call, but my function:

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,
        }
    );
}


You are using the hash-dereferencing operator ( %{ } ) on the first argument of your parameter list. But that argument is not a hash reference, it's just the string 'iconsize'. You can do what you want by one of two ways:

Pass an anonymous hash reference:

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

Or continue to pass a normal list, as you are right now, and change your function accordingly:

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

Notice in this version that we simply assign the argument list directly to the hash (after extracting $self). This works because a list of name => value pairs is just syntactic sugar for a normal list.

I prefer the second method, since there's no particularly good reason to construct an anonymous hashref and then dereference it right away.

There's also some good information on how this works in this post: Object-Oriented Perl constructor syntax.


You're violating strict refs by trying to use the string iconsize as a hash reference.

I think you just want:

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

The first argument will go into $self and the rest create the hash by taking pairs of items from the rest of @_.


Passing hash with parameters as list

You need to use @_ variable instead of shift. Like this:

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

There is different between hashes and references to hash in perl. Then you pass 'iconsize' => '32' as parameter this means list to perl, which can be interpreited as hash.

Passing hash with parameters as hash reference

But when you try %{ shift || {} } perl expect second parameter to be a hash references. In this case you can fix it in following way:

get_function_bar_begin({ 'iconsize' => '32' }); ## make anonymous hash for params


The problem is this line:

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

This does not pass a hash reference, as you seem to think, but a hash, which appears as a list to the callee. So when you do %{ shift }, you're only shifting the key 'iconsize', not the entire list. The solution is actually to make the second line of your function simpler:

my %template_params = @_;
0

精彩评论

暂无评论...
验证码 换一张
取 消