2011-03-17 236 views
1

比方说,我有这样的如何设置默认值?

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

$p的变量哈希可以有各种各样的价值观,他们还没有被定义的时候。我至少见过undef~''

如何将值-1指定为例如$profile{building}如果$p->{account}->{building}有这些奇怪的默认值之一?

有没有聪明的Perl方法来做到这一点?

更新:任何一个值,可以在任何陌生的默认值undef~''的。

回答

6

我想补充一个函数:

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

和执行功能的默认筛选逻辑。

或者,更好的是,预先将逻辑应用于$ p,以便知道$ p具有合理的值。

+1

+1将子名称更改为'磨砂',以确保敏感度。 – 2011-03-17 14:42:22

+0

$ p是只读的。你将如何编写擦洗功能?好主意。 – 2011-03-17 14:47:22

+0

是的,+1是明智的答案。 @Sandra:它检查参数是未定义还是“未定义”,并返回参数或-1。 – Tim 2011-03-17 14:57:17

0

这样的事情会照顾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, 
    ); 

(?我可以建议改进设计,以便它使用更一致的默认值)

+0

当然,我不知道默认您的实际需求,但我相信你能弄清楚如何将其切换到任何适合你的使用情况... :-) – 2011-03-17 14:33:09

+1

注意,这不会照顾''〜“'但是会照顾'0'。 – Tim 2011-03-17 14:33:47

+0

@Tim Nordenfur:是的,是的,我之前说过“假-y”。无需重复我已经说过的话。 – 2011-03-17 14:41:19

3

在Perl 5.10开始,你可以使用smart matching

my @vals = (undef, '~', ""); 
$profile{building} = $p->{account}{building} ~~ @vals ? -1 : $p->{account}{building}; 
1

如果使用5.10或更高版本我会去与@尤金的soluti上。否则......

对于不真实的价值观(民主, '',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

根据@ Arkadiy的回答 – 2011-03-17 14:53:33

4

所以,如果我正确地理解了你,你有一堆伪造的东西被用作“使用默认值”的标志。我不确定是否要将所有这些转换为-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;