2008-11-21 15 views
7

Piszę skrypt, który prawdopodobnie zostanie zmodyfikowany przez użytkowników. Obecnie przechowuję ustawienia konfiguracyjne wewnątrz skryptu. Istnieje w postaci hash-of-hashe.Jak mogę zmienić wielkość liter klawisza skrótu?

Chciałbym ochronić ludzi przed przypadkowym użyciem małych liter w klawiszach krzyżyka, ponieważ to złamie mój skrypt.

Byłoby łatwo przejrzeć skróty klawiszowe i wydawać ostrzeżenia tylko dla klawiszy z małymi literami, ale wolałbym automatycznie poprawiać wielkość liter.

Innymi słowy, chcę przekonwertować wszystkie klawisze mieszające w mieszaniu najwyższego poziomu na wielkie litery.

Odpowiedz

13

Andy'ego jest dobra odpowiedź, chyba że uc s każdy klawisz, a następnie uc s go ponownie, jeśli nie pasuje.

Ten uc s raz:

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

Ale skoro mówił o użytkownikach klucze przechowywania, krawat jest dużo bardziej pewny sposób, nawet jeśli wolniej.

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; 

A potem w główny:

tie my %hash, 'UCaseHash'; 

To show. "Magia" tie obejmuje je, więc użytkownicy nie mogą nieświadomie zadzierać z nim.

Oczywiście, tak długo jak używasz „klasa”, można przekazać w nazwie pliku config i zainicjować go stamtąd:

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; 
} 

Gdzie trzeba by nazwać to lubią:

... zakładając stałą wartość CONFIG_FILE_PATH.

+1

Wiesz, tam jest na CPAN moduł, który to robi. Nie ma potrzeby samodzielnego kodowania: Hash :: Case, zobacz http://search.cpan.org/dist/Hash-Case/ – bart

+0

Twoja metoda zastąpi cały skrót, a metoda Andy nadpisze tylko małe. O ile nie spodziewasz się, że hasz zawiera strasznie dużo małych liter (nie jest prawdopodobne w tym scenariuszu), nie będzie szybszy. –

+1

Dzięki za głowy, bart. Zapomniałem pierwszej zasady Klubu Perla: nie rozmawiaj, zanim nie sprawdziłeś CPAN. Mój post zaczął się prostą ilustracją związanej klasy, a potem mi się podobało. Doh! – Axeman

13

Przejdź przez skrót i zamień wszystkie małe litery na ich wielkie odpowiedniki, a następnie usuń stare. Z grubsza: odpowiedź

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

To przekonwertuje wielopoziomowe hash na małe

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; 
} 
Powiązane problemy