Technically, an attribute does not need to have a read or a write method. Most of the time it will, but not always. An example (graciously stolen from jrockway's comment is below:
has foo => (
isa => 'ArrayRef',
traits => ['Array'],
handles => { add_foo => 'push', get_foo => 'pop' }
)
This attribute will exist, but not have standard readers and writers.
So to test in every situation that an attribute has been defined as is => 'RO'
, you need to check both the write and the read method. You could do it with this subroutine:
# 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);
return unless defined $attribute;
return (! $attribute->get_write_method() && $attribute->get_read_method());
}
Alternatively, you could add a double negation before the last return
to boolify the return value:
return !! (! $attribute->get_write_method() && $attribute->get_read_method());