Это слишком долго для комментария, но это не прямой ответ на ваш вопрос.
Я хотел выяснить вашу структуру данных, которую, как я полностью понимаю, вы не можете контролировать.Мне любопытно, почему вы должны иметь дело с этим, и если у вас есть волосы или здравый смысл, осталось.
Множественные ссылки немного болезненны, но это также напоминает мне о глупых вещах, которые я делал раньшесо ссылками и тем, что я даже представил на первой конференции Perl.
Когда я впервые начал использовать ссылки, я глупо думал, что каждый раз, когда я хочу передать ссылку, мне приходится брать ссылку, даже есливещь уже была ссылкой.Я бы в итоге получил нечто уродливое, например $$$$ref
:
my $string = 'Buster';
some_sub( \$string );
sub some_sub {
my $ref = shift;
some_other_sub( \$ref );
}
sub some_other_sub {
my $ref = shift;
yet_another_sub( \$ref );
}
sub yet_another_sub {
my $ref = shift;
print "$$$$ref\n"; #fuuuuugly!
}
Это становится еще хуже, когда вы начинаете ссылаться на агрегаты, что, как мне кажется, происходит в вашей структуре данных.Поскольку ссылка на ссылку - это просто скаляр, как и исходная ссылка, вы не можете разыменовать ее, выстраивая подписки.Следовательно, все $${ }
в вашей строке.
Я не мог видеть, что происходило, пока не начал изнутри, и даже тогда я просто использовал метод проб и ошибок, пока не получил вещи, которые работали.
Первый уровень - это массивссылка, которая содержит ссылку на хеш-код в индексе 1. Это не так сложно и некрасиво:
my $j = 'foo';
my $e = 'baz';
my $h = [];
$h->[1] = { foo => 'bar' }; # to get to $$h[1]{$j}
print "1: $h->[1]{$j}\n";
Следующий уровень немного странный.Чтобы получить $${ ... }{proxy_cache}
, вам нужна ссылка на хеш-ссылку:
$h->[1] = {
foo => \ { proxy_cache => 'duck' } # ref to hash reference
};
print "2. $${ $$h[1]{$j} }{proxy_cache}\n";
Я не уверен, как вы строите эту структуру данных, но вы должны искать места, где у вас уже есть ссылка на хеши не брать еще один реф.Это глупость, которую я делал в молодости.Это может выглядеть так:
sub some_sub {
my $hash = shift;
$h->[1] = {
foo => \ $hash # don't do that!
};
Следующая часть не так уж и плоха.Это просто обычная ссылка на хеш в качестве значения (вместо duck
):
$h->[1] = {
foo => \ { proxy_cache => { $e => 'quux' } }
};
print "3. ${ $${ $$h[1]{$j} }{proxy_cache} }{$e}\n";
Следующий уровень - это еще одна ссылка на ссылку на хеш:
$h->[1] = {
foo => \ {
proxy_cache => {
$e => \ { fetch_handler => 'zap' }
}
}
};
print "4. $${ ${ $${ $$h[1]{$j} }{proxy_cache} }{$e} }{'fetch_handler'}\n";
Наконец, я получаюна последний ключ, ownerDocument
, и назначьте ссылку на подпрограмму:
$h->[1] = {
foo => \ {
proxy_cache => {
$e => \ { fetch_handler => {
ownerDocument => sub { print "Buster\n" },
}
}
}
}
};
print "5. $${ ${ $${ $$h[1]{$j} }{proxy_cache} }{$e} }{'fetch_handler'}{'ownerDocument'}\n";
Выходные данные - это CODE(0x.......)
, который вы уже видели.
Я хотел упростить это,но не так много, чтобы удалить из-за этих надоедливых неагрегированных ссылок.Это удаляет только три непробельных символа для выравнивания клавиши {$e}
:
print "6. ";
print $${ $${ $h->[1]{$j} }{proxy_cache}{$e} }{'fetch_handler'}{'ownerDocument'};
print "\n";