2008-11-21 59 views
7

我正在写一个可能被用户修改的脚本。目前我将配置设置存储在脚本中。它以哈希散列的形式存在。如何更改散列键的大小写?

我想防止人们不小心在散列键中使用小写字母,因为这会破坏我的脚本。

检查散列键并仅针对小写字母的任何键发出警告很简单,但我宁愿自动修复大小写。

换句话说,我想将顶级哈希中的所有哈希键都转换为大写。

回答

13

安迪的回答是一个很好的答案,但他uc小号每一个键,然后再uc的IT,如果它不匹配。

uc的IT一次:

%hash = map { uc $_ => $hash{$_} } keys %hash; 

但既然你说用户存储密钥的,平局是一个更可靠的方法,即使慢。

package UCaseHash; 
require Tie::Hash; 

our @ISA = qw<Tie::StdHash>; 

sub FETCH { 
    my ($self, $key) = @_; 
    return $self->{ uc $key }; 
} 

sub STORE { 
    my ($self, $key, $value) = @_; 
    $self->{ uc $key } = $value; 
} 

1; 

然后在主:

tie my %hash, 'UCaseHash'; 

这是一个秀。 “魔术”封装了它,所以用户不会在不知不觉中混淆它。

当然,只要您使用的是“阶级”,你可以通过在配置文件名称,并从那里初始化:

package UCaseHash; 
use Tie::Hash; 
use Carp qw<croak>; 

... 

sub TIEHASH { 
    my ($class_name, $config_file_path) = @_; 
    my $self = $class_name->SUPER::TIEHASH; 
    open my $fh, '<', $config_file_path 
     or croak "Could not open config file $config_file_path!" 
     ; 
    my %phash = _process_config_lines(<$fh>); 
    close $fh; 
    $self->STORE($_, $phash{$_}) foreach keys %phash; 
    return $self; 
} 

在那里你将不得不这样称呼它:

tie my %hash, 'UCaseHash', CONFIG_FILE_PATH; 

...假设一些常数CONFIG_FILE_PATH

+1

你知道,有CPAN上一个模块,做到这一点。无需自己编写代码:Hash :: Case,请参阅http://search.cpan.org/dist/Hash-Case/ – bart 2008-11-21 22:28:17

13

遍历散列并用大写字母替换所有小写字母,然后删除旧的小写字母。大致为:

for my $key (grep { uc($_) ne $_ } keys %hash) { 
    my $newkey = uc $key; 
    $hash{$newkey} = delete $hash{$key}; 
} 
0

这将转换的多层次哈希为小写

my $lowercaseghash = convertmaptolowercase(\%hash); 

sub convertmaptolowercase(){ 
    my $output=$_[0]; 
    while(my($key,$value) = each(%$output)){ 
     my $ref; 
     if(ref($value) eq "HASH"){ 
      $ref=convertmaptolowercase($value); 
     } else { 
      $ref=$value; 
     } 
     delete $output->{$key}; #Removing the existing key 
     $key = lc $key; 
     $output->{$key}=$ref; #Adding new key 
    } 
    return $output; 
}