Как установить значения по умолчанию? - PullRequest
1 голос
/ 17 марта 2011

Допустим, у меня есть такой хэш

my %profile = (
    building            => $p->{account}->{building},
    email               => $p->{account}->{email},
    phone               => $p->{account}->{phone},
    );

Переменные в $p могут иметь всевозможные значения, если они не были определены. Я хотя бы видел undef ~ ''.

Как мне присвоить значение -1, например, $profile{building} если у $p->{account}->{building} есть одно из этих странных значений по умолчанию?

Есть ли какой-нибудь умный способ Perl сделать это?

Обновление : Любое из значений может принимать любые странные значения по умолчанию undef ~ ''.

Ответы [ 5 ]

6 голосов
/ 17 марта 2011

Я бы добавил функцию:

my %profile = (
    building            => scrub($p->{account}->{building}),
    email               => scrub($p->{account}->{email}),
    phone               => scrub($p->{account}->{phone}),
    );

и реализовать логику фильтрации по умолчанию в функции.

Или, что еще лучше, предварительно примените логику к $ p, чтобы вы знали, что $ p имеет разумные значения.

4 голосов
/ 17 марта 2011

Так что, если я вас правильно понял, у вас есть куча поддельных вещей, которые используются в качестве флагов для «использования по умолчанию». Я не уверен, хотите ли вы перевести все это в -1 или в конкретные значения поля. Я приму несколько значений, просто чтобы все было сложнее.

# Make a hash of the wanted values
my %default_values = (
    building => -1,
    email    => 'N/A',
    phone    => 'unlisted',
);

# Make a hash of the values to replace.
# Skip undef, we have to check that separately
my %bogus_values = map {$_ => undef} ('', '~', 0);

# Copy the goodies into your final structure
my  %profile = map { 
    my $val = $p->{account}{$_};
    $val = $default_values{$_}
        if( not defined $val 
            or exists $bogus_values{$_}
        );
    $_ => $val;
} keys %default_values;


# Or copy them another way
my %profile = %default_values;
$profile{$_} = $p->{account}{$_}
    for grep {
        defined $p->{account}{$_}
        and not exists $bogus_values{$_}
    } keys %default_values;
3 голосов
/ 17 марта 2011

Начиная с Perl 5.10, вы можете использовать интеллектуальное сопоставление :

my @vals = (undef, '~', "");
$profile{building} = $p->{account}{building} ~~ @vals ? -1 : $p->{account}{building};
1 голос
/ 17 марта 2011

Если использовать 5.10 или выше, я бы выбрал решение @ eugene. В противном случае ...

Для неверных значений (undef, '', 0) вы можете сделать

building => $p->{account}->{building} || -1

Для истинных значений вам придется проверить явно, возможно, с помощью регулярного выражения:

building => !($p->{account}->{building} =~ m/~|char2|char3/)
            ? $p->{account}->{building}
            : -1

Объединение этих

building => $p->{account}->{building} || !($p->{account}->{building} =~ 
                                                             m/~|char2|char3/)
            ? $p->{account}->{building}
            : -1

В качестве альтернативы, чтобы упростить это и упростить тестирование и повторное использование, вы можете извлечь эту логику в подпункт:

sub scrub {
    my $value = shift;

    if (!$value or $value =~ m/~|char2|char3/) {
        return -1;
    }

    return $value;
}

А потом

my %profile = (
    building            => scrub( $p->{account}->{building} ),
    email               => scrub( $p->{account}->{email} ),
    phone               => scrub( $p->{account}->{phone} ),
    );
0 голосов
/ 17 марта 2011

Подобные вещи позаботятся о значениях FALSE (например, undef или '' или 0 или '0' или обо всем, что я пропустил):

my %profile = (
    building            => $p->{account}->{building} || -1,
    email               => $p->{account}->{email} || 'N/A',
    phone               => $p->{account}->{phone} || -1,
    );

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

<ч />

Или позаботиться о других значениях:

my %bad_values_hash = map { $_ => 1 } ('~', ''); # Put your bad values in here

my %profile = (
    building            => ($bad_values_hash{$p->{account}->{building}} ? -1 : $p->{account}->{building}) // -1,
    email               => ($bad_values_hash{$p->{account}->{email}} ? 'N/A' : $p->{account}->{email}) // 'N/A',
    phone               => ($bad_values_hash{$p->{account}->{phone}} ? -1 : $p->{account}->{phone}) // -1,
    );

(Могу ли я предложить усовершенствовать дизайн, чтобы он использовал более согласованные значения по умолчанию?)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...