6

現在、ブロック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");



UPDATE

答えてくれたfrido、Ether、Robert P、コメントしてくれたEther、Robert P、jrockwayに感謝します。

私は、Ether の答え$is_read_only!. 二重否定もそれを提供します。したがって、 coderef を出力せずに関数$is_read_only内で使用できます。is()

最も完全な回答については、以下の Robert P の回答を参照してください。誰もが非常に役に立ち、お互いの回答とコメントに基づいて構築されています。全体として、彼は私を最も助けてくれたと思うので、彼は現在受け入れられた回答としてマークされています。繰り返しになりますが、Ether、Robert P、frido、jrockway に感謝します。



疑問に思われるかもしれませんが、私が最初に行ったように、ここに と の違いに関するドキュメントがありますget_attribute( find_attribute_by_nameClass ::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.
4

3 に答える 3

5

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 を取得します。

于 2010-04-01T18:47:39.923 に答える
5

技術的には、属性は読み取りまたは書き込みメソッドを持つ必要はありません。 ほとんどの場合はそうですが、常にではありません。例 ( 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());
于 2010-04-02T16:51:56.897 に答える
3

オブジェクトのメタクラスからこれを取得できるはずです。

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

詳細については、 Class::MOP::Attributeを参照してください。

于 2010-04-01T18:48:19.537 に答える