From 2560d05044f5b778c86ea481ff43ad5255483be2 Mon Sep 17 00:00:00 2001 From: Damian Conway Date: Tue, 4 Dec 2007 03:17:24 +1100 Subject: [PATCH] Damian's last word and consistency adjustments about how Attribute::Handlers should behave on 5.10.0. See: Subject: Re: [PATCH] Attribute::Handlers till ears are bleeding Message-ID: <47539164.3030906@conway.org> p4raw-id: //depot/perl@32582 --- lib/Attribute/Handlers.pm | 46 +++++++++++++++++++-------------- lib/Attribute/Handlers/t/data_convert.t | 4 +-- lib/Attribute/Handlers/t/linerep.t | 12 +++++---- 3 files changed, 35 insertions(+), 27 deletions(-) diff --git a/lib/Attribute/Handlers.pm b/lib/Attribute/Handlers.pm index aa4eada..e035a14 100644 --- a/lib/Attribute/Handlers.pm +++ b/lib/Attribute/Handlers.pm @@ -192,11 +192,11 @@ sub _apply_handler_AH_ { no warnings; my $evaled = !$raw && eval("package $pkg; no warnings; no strict; local \$SIG{__WARN__}=sub{die}; [$data]"); - $data = $evaled || [$data]; + $data = $evaled unless $@; $pkg->$handler($sym, (ref $sym eq 'GLOB' ? *{$sym}{ref $ref}||$ref : $ref), $attr, - (@$data>1? $data : $data->[0]), + $data, $phase, $filename, $linenum, @@ -390,40 +390,46 @@ which it belongs, so the symbol table argument (C<$_[1]>) is set to the string C<'LEXICAL'> in that case. Likewise, ascribing an attribute to an anonymous subroutine results in a symbol table argument of C<'ANON'>. -The data argument passes in the value (if any) associated with the +The data argument passes in the value (if any) associated with the attribute. For example, if C<&foo> had been declared: sub foo :Loud("turn it up to 11, man!") {...} -then the string C<"turn it up to 11, man!"> would be passed as the -last argument. +then a reference to an array containing the string +C<"turn it up to 11, man!"> would be passed as the last argument. Attribute::Handlers makes strenuous efforts to convert the data argument (C<$_[4]>) to a useable form before passing it to the handler (but see L<"Non-interpretive attribute handlers">). +If those efforts succeed, the interpreted data is passed in an array +reference; if they fail, the raw data is passed as a string. For example, all of these: - sub foo :Loud(till=>ears=>are=>bleeding) {...} - sub foo :Loud(['till','ears','are','bleeding']) {...} - sub foo :Loud(qw/till ears are bleeding/) {...} - sub foo :Loud(qw/my, ears, are, bleeding/) {...} - sub foo :Loud(till,ears,are,bleeding) {...} + sub foo :Loud(till=>ears=>are=>bleeding) {...} + sub foo :Loud(qw/till ears are bleeding/) {...} + sub foo :Loud(qw/my, ears, are, bleeding/) {...} + sub foo :Loud(till,ears,are,bleeding) {...} causes it to pass C<['till','ears','are','bleeding']> as the handler's -data argument. However, if the data can't be parsed as valid Perl, then -it is passed as an uninterpreted string. For example: +data argument. While: + + sub foo :Loud(['till','ears','are','bleeding']) {...} - sub foo :Loud(my,ears,are,bleeding) {...} - sub foo :Loud(qw/my ears are bleeding) {...} +causes it to pass C<[ ['till','ears','are','bleeding'] ]>; the array +reference specified in the data being passed inside the standard +array reference indicating successful interpretation. + +However, if the data can't be parsed as valid Perl, then +it is passed as an uninterpreted string. For example: -cause the strings C<'my,ears,are,bleeding'> and C<'qw/my ears are bleeding'> -respectively to be passed as the data argument. + sub foo :Loud(my,ears,are,bleeding) {...} + sub foo :Loud(qw/my ears are bleeding) {...} -If the attribute has only a single associated scalar data value, that value is -passed as a scalar. If multiple values are associated, they are passed as an -array reference. If no value is associated with the attribute, C is -passed. +cause the strings C<'my,ears,are,bleeding'> and +C<'qw/my ears are bleeding'> respectively to be passed as the +data argument. +If no value is associated with the attribute, C is passed. =head2 Typed lexicals diff --git a/lib/Attribute/Handlers/t/data_convert.t b/lib/Attribute/Handlers/t/data_convert.t index b0c37c3..5d65e31 100644 --- a/lib/Attribute/Handlers/t/data_convert.t +++ b/lib/Attribute/Handlers/t/data_convert.t @@ -26,7 +26,7 @@ sub test1 :Loud(till=>ears=>are=>bleeding) { } sub test2 :Loud(['till','ears','are','bleeding']) { - [qw(till ears are bleeding)] + [[qw(till ears are bleeding)]] } sub test3 :Loud(qw/till ears are bleeding/) { @@ -50,5 +50,5 @@ sub test7 :Loud(qw/my ears are bleeding) { } sub test8 :Loud("turn it up to 11, man!") { - 'turn it up to 11, man!'; + ['turn it up to 11, man!']; } diff --git a/lib/Attribute/Handlers/t/linerep.t b/lib/Attribute/Handlers/t/linerep.t index 9a2188b..9b3da8e 100644 --- a/lib/Attribute/Handlers/t/linerep.t +++ b/lib/Attribute/Handlers/t/linerep.t @@ -7,7 +7,7 @@ BEGIN { } } -use Test::More tests => 16; +use Test::More tests => 18; use Attribute::Handlers; sub Args : ATTR(CODE) { @@ -16,10 +16,11 @@ sub Args : ATTR(CODE) { is( $symbol, \*foo, 'symbol' ); is( $referent, \&foo, 'referent' ); is( $attr, 'Args', 'attr' ); - is( $data, 'bar', 'data' ); + is( ref $data, 'ARRAY', 'data' ); + is( $data->[0], 'bar', 'data' ); is( $phase, 'CHECK', 'phase' ); is( $filename, __FILE__, 'filename' ); - is( $linenum, 25, 'linenum' ); + is( $linenum, 26, 'linenum' ); } sub foo :Args(bar) {} @@ -32,11 +33,12 @@ sub SArgs : ATTR(SCALAR) { is( $symbol, 'LEXICAL', 'symbol' ); is( $referent, \$bar, 'referent' ); is( $attr, 'SArgs', 'attr' ); - is( $data, 'grumpf', 'data' ); + is( ref $data, 'ARRAY', 'data' ); + is( $data->[0], 'grumpf', 'data' ); is( $phase, 'CHECK', 'phase' ); TODO: { local $TODO = "Doesn't work correctly"; is( $filename, __FILE__, 'filename' ); - is( $linenum, 25, 'linenum' ); + is( $linenum, 28, 'linenum' ); } } -- 2.7.4