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 = @_;
精彩评论