LINUX.ORG.RU

Обьясните, почему оно так

 , ,


0

2

Есть код на Perl:

use strict;
use warnings;
 
my %hash = (
    one => 1,
    two => 2,
    four => 4,
);
 
my @required_keys = qw(two three four);
my %result_hash = map { $_ => $hash{$_} if (exists $hash{$_}) } @required_keys;
 
use Data::Dumper;
print 'Resulting hash: ' . Dumper(\%result_hash);

И результат его выполнения: http://ideone.com/ZAVwt6
Для Ъ:

Resulting hash: $VAR1 = {
          '' => 'four',
          '4' => undef,
          'two' => 2
        };

Вопрос: откуда берётся пустая строка в ключах хеша?

P.S. Корректная работа получается таким кодом:

map { exists $hash{$_} ? ($_ => $hash{$_}) : () } @required_keys;
или так:
map { $_ => $hash{$_} } grep { exists $hash{$_} } @required_keys;

И на perldoc есть похожий пример: http://perldoc.perl.org/functions/map.html

my @squares = map { $_ > 5 ? ($_ * $_) : () } @numbers;

★★★★★

Последнее исправление: KennyMinigun (всего исправлений: 1)

> Вопрос: откуда берётся пустая строка в ключах хеша?

первый элемент — «two»: ключ «two» в хеше есть, мап возвращает список ('two', 2).

второй элемент — «three»: в хеше отсутствует, условие не выполняется, возвращается undef.

третий элемент — «four»: ключ «four» в хеше есть, мап возвращает список ('four', 4).

итого, получается список: ('two', 2, undef, 'four', 4). добавляем для чётности undef: ('two', 2, undef, 'four', 4, undef) и разбиваем на пары: ('two' => 2, undef => 'four', 4 => undef). т.к. undef не может быть ключом, он заменяется на пустую строку: ('two' => 2, " => 'four', 4 => undef).

arsi ★★★★★
()
Ответ на: комментарий от arsi

второй элемент — «three»: в хеше отсутствует, условие не выполняется, возвращается undef

Так в том, то и дело, что там нигде явно не возвращается undef. По логике должно быть как с «пустым значением» в списочном контексте: http://ideone.com/HlQId6

undef не может быть ключом, он заменяется на пустую строку

И правда: http://ideone.com/BJNWBf

KennyMinigun ★★★★★
() автор топика
Ответ на: комментарий от KennyMinigun

> Так в том, то и дело, что там нигде явно не возвращается undef. По логике должно быть как с «пустым значением» в списочном контексте

во-первых, я там затупил :) для «three» возвращается ", стандартный эквивалент false в перле.

во-вторых, возвращается последнее вычисленное значение. в мапе для элемента «three» последним вычисленным значением было false (") оператора exists, его ты и получил.

arsi ★★★★★
()
%result_hash = map { $_ => $hash{$_} } grep { exists $hash{$_} } @required_keys;
outtaspace ★★★
()
Ответ на: комментарий от arsi

в мапе для элемента «three» последним вычисленным значением было false (") оператора exists, его ты и получил.

А, спасибо, прояснилось.

KennyMinigun ★★★★★
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.