Как сослаться на скаляр в хеш-ссылке в Perl?

Простой вопрос:

Как мне сделать это в одной строке:

my $foo = $bar->{baz};
fizz(\$foo);

Я пробовал \$bar->{baz}, \${$bar->{baz}} и многие другие. Это вообще возможно?

-fREW

Обновление: хорошо, хэш-ссылка поступает из DBI, и я передаю скалярную ссылку в инструментарий шаблона. Я предполагаю, что теперь, когда я смотрю более внимательно, проблема как-то связана с тем, как TT делает все это. Фактически я хочу сказать:

$template->process(\$row->{body}, $data);

Но TT так не работает, TT берет скалярную ссылку и помещает туда данные, так что мне придется сделать это:

$template->process(\$row->{body}, $shopdata, \$row->{data});

В любом случае спасибо за помощь. По крайней мере, у меня будет только одна ссылка вместо двух.


person Frew Schmidt    schedule 25.11.2008    source источник
comment
Основываясь на том, что вы, возможно, пытаетесь сделать, вам следует взглянуть на опцию EXPOSE_BLOCKS в TT. Это позволяет вам обрабатывать блоки в шаблоне несколько раз... $template-›process(table.tt/row, { data =› 1 } ); и затем в шаблоне table.tt [% BLOCK row %]‹tr›‹td›[% data %]‹/td›‹/tr›[% END %]   -  person draegtun    schedule 25.11.2008
comment
Что касается вашего обновления, см. обновление моего ответа.   -  person runrig    schedule 05.01.2009


Ответы (4)


\$bar->{baz}

должно сработать.

E.g.:

my $foo;
$foo->{bar} = 123;

my $bar = \$foo->{bar};

$$bar = 456;

print "$foo->{bar}\n";   # prints "456"

В ответ на обновление в ОП вы можете сделать:

\@$row{qw(body data)};

Это не то же самое, что \@array, который создает одну ссылку на массив. Приведенное выше будет распространять ссылку и составлять список из двух ссылок.

person runrig    schedule 25.11.2008

\$bar->{baz}, похоже, помогает мне:

my $bar = { baz => 1 };
print $bar->{baz}, "\n";  # prints 1
my $ref =  \$bar->{baz};
print $$ref, "\n";        # prints 1
$$ref = 2;
print $bar->{baz}, "\n";  # prints 2 
person Yanick    schedule 25.11.2008

Вы не показали, как были настроены %bar и fizz(), поэтому я настроил их так:

my %hash;
my $bar = \%hash;
$hash{baz} = "found it\n";
sub fizz {
  my $ref = shift;
  print $$ref;
}

Тогда оба из них работают, ваш оригинал:

my $foo = $bar->{baz};
fizz(\$foo);

и один из вариантов, которые вы сказали, что пробовали:

fizz(\$bar->{baz});

Можете ли вы показать ошибку, которая дает вам?

person jimtut    schedule 25.11.2008

Я даже не уверен, что вы делаете. Вы также должны заключать в кавычки baz.

Теперь давайте рассмотрим, что вы присваиваете скаляру скаляр в первой строке, тогда вторая строка должна работать. Однако я действительно не знаю, то ли это то, что вы здесь пытаетесь, и это не имеет смысла в Perl. Использование ссылок часто используется в других языках для

  1. ускорить вызов функции
  2. разрешить возврат нескольких значений.

Теперь первый обычно не нужен со скалярами, и в любом случае Perl — это язык сценариев, поэтому, если вас действительно беспокоит скорость, пишите C.

Второй не нужен в Perl, так как вы можете легко возвращать списки и ссылки на анонимные хэши.

Вы смотрели на "man perlref"?

person Ralf    schedule 25.11.2008
comment
Нет причин заключать baz в кавычки. Perl автоматически заключает в кавычки хеш-ключи, если они полностью состоят из символов \w. - person runrig; 25.11.2008
comment
Кроме того, передача скалярных ссылок полезна, например, в биоинформатике, где вы можете избежать копирования больших объемов данных. - person runrig; 25.11.2008