Damian's last word and consistency adjustments about how Attribute::Handlers
Damian Conway [Mon, 3 Dec 2007 16:17:24 +0000 (03:17 +1100)]
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
lib/Attribute/Handlers/t/data_convert.t
lib/Attribute/Handlers/t/linerep.t

index aa4eada..e035a14 100644 (file)
@@ -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<undef> 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<undef> is passed.
 
 =head2 Typed lexicals
 
index b0c37c3..5d65e31 100644 (file)
@@ -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!'];
 }
index 9a2188b..9b3da8e 100644 (file)
@@ -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' );
     }
 }