代码之家  ›  专栏  ›  技术社区  ›  Christopher Bottoms zerkms

有没有简单的方法来测试Moose属性是只读的?

  •  6
  • Christopher Bottoms zerkms  · 技术社区  · 16 年前

    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");
    



    更新



    我喜欢以太的回答 $is_read_only ! . Double negation 也规定了这一点。因此,您可以使用 $是只读的 在一个 is()



    如果您可能想知道,正如我一开始所做的,这里是关于 get_attribute find_attribute_by_name ( from Class::MOP::Class ):

    $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.
    
    3 回复  |  直到 9 年前
        1
  •  5
  •   Community Mohan Dere    9 年前

    从技术上讲,属性不需要有读或写方法。 有时会,但不总是。一个例子(优雅地从 jrockway's comment

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

    所以要在每种情况下测试一个属性被定义为 is => 'RO' ,您需要同时检查write和read方法。您可以使用以下子例程:

    # 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());
    
        2
  •  5
  •   Ether    16 年前

    如中所述 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() 将获取writer方法(您创建的方法或生成的方法),如果没有,则获取undef。

        3
  •  3
  •   friedo    16 年前

    您应该能够从对象的元类中获取:

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

    看到了吗 Class::MOP::Attribute