В Perl, как я могу назвать метод, имя которого я имею в строке?

Я пытаюсь записать некоторый псевдокод для поиска списка подобных объектов для первого, атрибуты которого соответствуют определенным значениям. Чтобы сделать это, я должен назвать набор методов доступа и проверить все их значения один за другим. Я хотел бы использовать абстракцию как это:

sub verify_attribute {
    my ($object, $attribute_method, $wanted_value) = @_;
    if ( call_method($object, $attribute_method) ~~ $wanted_value ) {
        return 1;
    }
    else {
        return;
    }
}

Затем я могу циклично выполниться через хеш, ключи которого являются именами метода доступа и чьи значения являются значениями, которые я ищу для тех атрибутов. Например, если тот хеш называют %wanted, Я мог бы использовать код как это для нахождения объекта, который я хочу:

my $found_object;
FINDOBJ: foreach my $obj (@list_of_objects) {
    foreach my $accessor (keys %wanted) {
        next FINDOBJ unless verify_attribute($obj, $accessor, $wanted{$accessor});
    }
    # All attrs verified
    $found_object = $obj;
    last FINDOBJ;
}

Конечно, единственная проблема - это call_method не экс-находится. Или он? Как я могу назвать метод, если у меня есть строка, содержащая ее имя? Или есть ли лучшее решение этой целой проблемы?

6
задан Sinan Ünür 27 April 2010 в 14:11
поделиться

1 ответ

my $found_object;
FINDOBJ: foreach my $obj (@list_of_objects) {
  foreach my $accessor (keys %wanted) {
    next FINDOBJ unless $obj->$accessor() == $wanted{$accessor};
  }
  # All attrs verified
  $found_object = $obj;
  last;
}

Да, вы можете вызывать методы таким образом. Никакая строка (или любой другой) eval не задействована. Кроме того, замените == на eq или = ~ в зависимости от типа данных ...

Или, для дополнительных кредитов, сделайте это функциональным способом: (all () действительно должен быть частью List :: Util!)

use List::Util 'first';

sub all (&@) {
  my $code = shift;
  $code->($_) || return 0 for @_;
  return 1;
}

my $match = first {
                    my $obj = $_;
                    all { $obj->$_ == $attrs{$_} }
                      keys %wanted
                  } @list_of_objects;

Обновление: по общему признанию, первое решение является менее запутанным, поэтому предпочтительнее . Но, отвечая на вопросы, вы добавили немного сахара, чтобы вам было интересно! ; -)

5
ответ дан 17 December 2019 в 04:44
поделиться
Другие вопросы по тегам:

Похожие вопросы: