Существует ли простой способ протестировать, если атрибут Американского лося только для чтения?

Я в настоящее время использую блок eval для тестирования этого, я установил атрибут как только для чтения. Существует ли более простой способ сделать это?

Пример из рабочего кода:

#Test that sample_for is ready only
eval { $snp_obj->sample_for('t/sample_manifest2.txt');};
like($@, qr/read-only/xms, "'sample_for' is read-only");



ОБНОВЛЕНИЕ

Благодаря friedo, Эфиру и Robert P для их ответов и к Эфиру, Robert P и jrockway для их комментариев.

Мне нравится, как ответ Эфира гарантирует это $is_read_only только истинное или ложное значение (т.е. но никогда coderef) путем отрицания его с a !. Двойное отрицание также обеспечивает это. Таким образом можно использовать $is_read_only в is() функция, без него распечатывающий coderef.

См. ответ P Robert ниже для самого полного ответа. Все были очень полезны и основывались на ответах друг друга и комментариях. В целом, я думаю, что он помог мне больше всего, следовательно его теперь отмечен принятый ответ. Снова, благодаря Эфиру, Robert P, friedo, и jrockway.



В случае, если Вы могли бы задаваться вопросом, как я сделал сначала, вот документация о различии между get_attribute и find_attribute_by_name (от Класса:: MOP:: Класс):

$metaclass->get_attribute($attribute_name)

    This will return a Class::MOP::Attribute for the specified $attribute_name. If the 
    class does not have the specified attribute, it returns undef.

    NOTE that get_attribute does not search superclasses, for that you need to use
    find_attribute_by_name.

6
задан Community 23 May 2017 в 10:27
поделиться

3 ответа

Технически атрибуту не обязательно иметь метод чтения или записи. Чаще всего будет, но не всегда. Пример (любезно украденный из комментария jrockway ) ниже:

has foo => ( 
    isa => 'ArrayRef', 
    traits => ['Array'], 
    handles => { add_foo => 'push', get_foo => 'pop' }
)

Этот атрибут будет существовать, но не будет иметь стандартных читателей и писателей.

Таким образом, чтобы в каждой ситуации проверить, что атрибут был определен как is => 'RO' , вам необходимо проверить как метод записи, так и метод чтения. Вы можете сделать это с помощью этой подпрограммы:

# returns the read method if it exists, or undef otherwise.
sub attribute_is_read_only {
    my ($obj, $attribute_name) = @_;
    my $attribute = $obj->meta->get_attribute($attribute_name);

    return unless defined $attribute;
    return (! $attribute->get_write_method() && $attribute->get_read_method());
}

В качестве альтернативы вы можете добавить двойное отрицание перед последним return , чтобы логически преобразовать возвращаемое значение:

return !! (! $attribute->get_write_method() && $attribute->get_read_method());
5
ответ дан 8 December 2019 в 18:34
поделиться

Как описано в Class :: MOP :: Attribute :

my $attr = $this->meta->find_attribute_by_name($attr_name);
my $is_read_only = ! $attr->get_write_method();

$ attr-> get_write_method () получит метод записи (созданный вами или созданный) или undef, если его нет.

5
ответ дан 8 December 2019 в 18:34
поделиться

Sie sollten dies aus der Metaklasse des Objekts abrufen können:

unless ( $snp_obj->meta->get_attribute( 'sample_for' )->get_write_method ) { 
    # no write method, so it's read-only
}

Weitere Informationen finden Sie unter Class::MOP::Attribute.

3
ответ дан 8 December 2019 в 18:34
поделиться
Другие вопросы по тегам:

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