LINUX.ORG.RU

Хеш в Perl, обойтись без exists и defined


0

0

Хочу, чтобы для любого отсутствующего ключа хеш возвращал какое-то 
значение, например:

my %h=(
      "a1" => sub {
                  print "a\n";
                 }
      "a2" => sub {
                  print "b\n";
                 }
      undef => sub {
                     print "unknown value \n";
                   }
      )


Далее, 

&{$h{"a1"}};#Напечатает a
&{$h{"a"}}; #Напечатает unknown value
&{$h{"a2"}};#Напечатает unknown value

К сожалению, как я написал не работает и я не уверен, что
вообще возможно, но я не гуру в Perl, поэтому подскажите
что-нибудь.

А то задумал так красиво всё и нехочется портить красоту всякими
if (exists
К тому же лишняя проверка - лишние расходы на исполнение в циклах,
особенно глубоких.
anonymous

Ответ на: комментарий от vahvarh

Спасибо, о таком способе я как-то и не подумал. Буду его использовать, если все-таки нет, конструкции хеша, вроде той что я привел. Потому что она универсальная и ее можно в модуль засунуть, а по-твоему хоть и хороший вариант, но вынуждает каждый раз его явно прописывать.

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

Правильно всё-таки делать в классе

sub get {
 my ($self,$val)=@_;
 return sub {} unless $self->{$val};
 return $self->{$val};
}

а вызывать как

&{$myref->get("hello")}();

Тем более что в ->get могуть быть более сложные ситуации

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

Наверное так правильнее всего. Спасибо!

anonymous
()

Сделай свой собственный хеш на базе Tie::StdHash и переопредели
нужные метод[ы] (FETCH). Ниже пример, как возвращать default строку,
аналогично можешь возвращаить code refernce.


#!/usr/bin/perl -w

use strict;

package HashWithDefaultValue;
use Tie::Hash;
our @ISA = 'Tie::StdHash';
                                                                                         
sub FETCH
{
    my $self = shift;
    my $key  = shift;
    exists $self->{$key} ? $self->{$key} : "SOME DEFAULT VALUE";
}


package main;

tie my %new_hash, 'HashWithDefaultValue';

$new_hash{A} = "Value for A";

print $new_hash{A}, "\n", $new_hash{NON_EXESTENT}, "\n";

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

Спасибо. Интересно.

Однако сколько нового можно узнать, захотев сделать код покрасивее.

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

Использовать perl, не прочитав Perl CookBook - преступление.

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