Почему я не могу сказать что $somehash печати {$var} {fh} “нечто”?

Просто ради полноты:

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

Проблема может быть решена путем использования односторонней привязки (@{}), так как при изменении текста текстовое представление будет запускать своих собственных слушателей и пытаться изменить наблюдаемое, отправляя его в бесконечное число рекурсии.

8
задан GEOCHET 5 March 2009 в 23:11
поделиться

3 ответа

см. http://perldoc.perl.org/functions/print.html

Обратите внимание, что при хранении ДЕСКРИПТОРОВ ФАЙЛОВ в массиве, или если Вы используете какое-либо другое выражение, более сложное, чем скалярная переменная для получения его, необходимо будет использовать блок, возвращающий значение дескриптора файла вместо этого:...

Так, в Вашем случае Вы использовали бы блок как это:

print { $somehash{$var}{fh} } "foo";
22
ответ дан 5 December 2019 в 04:58
поделиться

Вышеупомянутые ответы все корректны. Причина, которую они не позволяют полному выражению там, print FH LIST уже довольно странный синтаксис. Помещать что-либо более сложное там представило бы тонну неоднозначного синтаксиса. Блок удалил ту неоднозначность.

Для наблюдения, куда это безумие приводит к рассмотрите ужас, который является синтаксисом косвенного дополнения.

foo $bar;  # Is that foo($bar) or $bar->foo()?  Good luck!
5
ответ дан 5 December 2019 в 04:58
поделиться

Если у Вас есть что-нибудь кроме простого скаляра как Ваш дескриптор файла, необходимо перенести ссылку, содержащую дескриптор файла в фигурных скобках, таким образом, Perl знает, как проанализировать оператор:

print { $somehash{$var}{fh} } $foo;

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

Синтаксис нечетен потому что print косвенный метод на объекте дескриптора файла:

method_name Object @arguments;

Вы, возможно, видели это в олдскульном CGI.pm. Вот два косвенных вызова метода:

use CGI;

my $cgi_object = new CGI 'cat=Buster&bird=nightengale';

my $value = param $cgi_object 'bird';

print "Indirect value is $value\n";

Это почти хорошо работает (см. ответ Schwern о неоднозначности), как долго как объект находится в простом скаляре. Однако, если я поместил $cgi_object в хеше я получаю ту же синтаксическую ошибку, с которой Вы добрались print. Я могу поместить фигурные скобки вокруг доступа хеша, чтобы заставить его удаться. Продолжая предыдущий код:

my %hash;

$hash{animals}{cgi} = $cgi_object;

# $value = param $hash{animals}{cgi} 'cat';  # syntax error
$value = param { $hash{animals}{cgi} } 'cat';
print "Braced value is $value\n";

Это все немного неуклюже, поэтому просто используют нотацию стрелки для всего вместо этого:

my $cgi_object = CGI->new( ... );
$cgi_object->param( ... );

$hash{animals}{cgi}->param( ... );

Можно сделать то же с дескрипторами файлов, хотя необходимо использовать IO:: модуль Дескриптора, чтобы заставить все это удаться:

use IO::Handle;

STDOUT->print( 'Hello World' );

open my( $fh ), ">", $filename or die ...;
$fh->print( ... );

$hash{animals}{fh} = $fh;

$hash{animals}{fh}->print( ... );
10
ответ дан 5 December 2019 в 04:58
поделиться
Другие вопросы по тегам:

Похожие вопросы: