Как был бы я создавать хеш как следование:
my %hash = (key1=>"Something", key2=>$hash{key1} . "Else");
Разве это не может быть сделано в то время как, когда я объявляю хеш? До сих пор единственная вещь, которую я придумал, была:
my %hash = (key1=>"Something");
$hash{key2} = $hash{key1} . "Else";
Почему бы не использовать промежуточную переменную?
my $common_value = 'Something';
my %some_hash = ( k1 => $common_value, k2 => $common_value.'Else' );
Обновление
kemp спросило, зачем нам нужна промежуточная переменная. Я могу интерпретировать этот вопрос двумя способами, постараюсь ответить на обе интерпретации.
Почему вы не можете сделать мой %hash = ( k1 => 'foo', k2 => $hash{k1}. 'bar');
?
Правая сторона (rhs) выражения оценивается перед левой стороной (lhs). Таким образом, когда определяется значение для k2
, ассигнация к %hash
еще не произошла. На самом деле %hash
еще даже не создан и не введен в блокнот. (%hash
здесь лексическая переменная, поэтому она не попадет в таблицу символов.)
Зачем использовать переменную, а не другой метод?
Ну, есть много способов инициализировать хэш такими значениями. Я бы использовал промежуточную переменную, если бы у меня было небольшое количество родственных ключей для инициализации.
мой $cv1 = sub_result() * 5;
мой $cv2 = "Число: $cv1";
my %h = (
k1 => $cv1,
k2 => $cv2,
k3 => "Numero: $cv1",
k4 => "Большие $cv2",
k5 => "Круглый $cv2",
k6 => "Целый $cv2",
k7 => "-$cv1",
);
Однако, если бы мне пришлось строить много сложных значений, которые зависели бы от множества различных ключей, я бы, вероятно, использовал подход, основанный на данных, для инициализации хэша. Точная реализация зависела бы от деталей, которых у меня нет, но это могло бы выглядеть следующим образом:
используйте Scalar::Util qw(reftype);
my @init = (
[ клавиша 1 = ] Стоимость ],
[ key2 => \&make_a_value, 'key1' ],
[ key3 => \&another_way, 'key2' ],
);
мой %h;
за мой $spec ( @init ) {
мой $key = сдвиг @$spec;
my $value = shift @$spec;
my @args = @$spec;
if( reftype $value eq reftype sub {} ) {
$значение = $значение->( @h{ @args } );
}
$h{$key} = $value;
}
В любом случае, когда этот вопрос организован, выбор метода зависит от многих деталей, которые являются специфическими для данного случая. Таким образом, мы остаемся с необходимостью делать общие утверждения. Промежуточные переменные - это один из хороших способов подхода к проблеме ОП. Должны ли они использоваться в его конкретном случае, я не могу сказать.
В точке, где вы определяете хеш, $ Hash {Key1} не существует, поэтому вы не можете сделать это в одном утверждении. Вы можете сделать свое собственное решение и использовать клавишу ключа1 после того, как вы определили его.
Что не так с
my %hash = ( key1 => "Something", key2 => "Something" . "Else" );
?
Да, я знаю, что это заполнители, но все, что они, возможно, вы знаете их в то время, когда вы строете хэш (или вы не построили Это вообще), так почему бы тебе просто присоединиться к ним вместе?
Вы можете получить довольно близко, но я не уверен, что он имеет ценность, кроме новинки:
$_->{key2} = $_->{key1} . "Else" for my $hash = { key1 => "Something" };
При создании промежуточной переменной снаружи от% HAHH отключается, затем использование блока DO
может сделать его более эстетически приятным:
my %hash = (
do {
my $s = 'Something';
( key1 => $s, key2 => $s . 'Else' );
},
);
/ I3AZ /
Во-первых, я бы сделал это с промежуточным значением. Но у вас есть еще два отдельных дополнительных варианта. Я не предлагаю ни одну из них, если вы новичок в perl - на самом деле мне больше всего нравится решение с промежуточным значением, но для полноты:
->{key1}
), дополнительную информацию об этом методе можно найти с помощью perldoc perltie
, а также на man-странице, ссылки на которую приведены выше для Tie: :Hash
;Вот пример Moose.
package Class;
use Moose;
has [qw/key1 key2/] => ( isa => 'Str', is => 'rw', init_arg => 'key1' );
my $o = Class->new( { key1 => 'foobar' } );
print $o->key1, $o->key2;
Это не может быть сделано по 2 причинам:
в процессах времени Perl Key2 => $ Hash {Key1}
, он еще не связал память, выделенную Ключ 1 с хеш-именем хеш. Другими словами, $ hash {Key1}
не указывает на правильное место в памяти до Key2 => $ Hash {Key1}
уже назначается.
Предыдущая причина не составила дополнительную проблему: вы еще не разместили % HASH
в таблицу символов к тому времени, когда вы обрабатываете Key2 => $ Hash {Key1}
(Опять же порядок анализа / оценки), поэтому компилятор будет BARF, если вы используете строгий;
, как вы всегда должны. Этот легко крестится с объявлением моего% HASH
в предыдущем операторе, но № 1 нет.