summaryrefslogtreecommitdiff
path: root/lib/Attribute
diff options
context:
space:
mode:
authorDavid Feldman <david.feldman@tudor.com>2006-10-25 12:34:26 -0400
committerRafael Garcia-Suarez <rgarciasuarez@gmail.com>2006-11-09 15:58:11 +0000
commitcab6c672e9819e2fc0a67e60c3b18ff6c0385dac (patch)
treeac806fade85e470a26c9996ef1051ac5e2eb53ee /lib/Attribute
parent4bd7b839c96352aa075f714f4c1aaa963c29018e (diff)
downloadperl-cab6c672e9819e2fc0a67e60c3b18ff6c0385dac.tar.gz
Add to Attribute::Handlers the ability to report caller's file and line
number. Based on: Subject: FW: Attribute::Handlers From: "David Feldman" <David.Feldman@tudor.com> Message-ID: <BA9AB162DD5CED46AC03DC5904B19C5B3736B4@tudor.com> plus docs and tests. p4raw-id: //depot/perl@29243
Diffstat (limited to 'lib/Attribute')
-rw-r--r--lib/Attribute/Handlers.pm46
-rw-r--r--lib/Attribute/Handlers/t/linerep.t42
-rw-r--r--lib/Attribute/Handlers/t/multi.t9
3 files changed, 80 insertions, 17 deletions
diff --git a/lib/Attribute/Handlers.pm b/lib/Attribute/Handlers.pm
index b1986bd094..a9ce6b0537 100644
--- a/lib/Attribute/Handlers.pm
+++ b/lib/Attribute/Handlers.pm
@@ -2,7 +2,7 @@ package Attribute::Handlers;
use 5.006;
use Carp;
use warnings;
-$VERSION = '0.78_03';
+$VERSION = '0.78_04';
# $DB::single=1;
my %symcache;
@@ -114,6 +114,7 @@ sub _gen_handler_AH_() {
return sub {
_resolve_lastattr;
my ($pkg, $ref, @attrs) = @_;
+ my (undef, $filename, $linenum) = caller 2;
foreach (@attrs) {
my ($attr, $data) = /^([a-z_]\w*)(?:[(](.*)[)])?$/is or next;
if ($attr eq 'ATTR') {
@@ -141,7 +142,7 @@ sub _gen_handler_AH_() {
my $handler = $pkg->can("_ATTR_${type}_${attr}");
next unless $handler;
my $decl = [$pkg, $ref, $attr, $data,
- $raw{$handler}, $phase{$handler}];
+ $raw{$handler}, $phase{$handler}, $filename, $linenum];
foreach my $gphase (@global_phases) {
_apply_handler_AH_($decl,$gphase)
if $global_phases{$gphase} <= $global_phase;
@@ -172,7 +173,7 @@ push @UNIVERSAL::ISA, 'Attribute::Handlers::UNIVERSAL'
sub _apply_handler_AH_ {
my ($declaration, $phase) = @_;
- my ($pkg, $ref, $attr, $data, $raw, $handlerphase) = @$declaration;
+ my ($pkg, $ref, $attr, $data, $raw, $handlerphase, $filename, $linenum) = @$declaration;
return unless $handlerphase->{$phase};
# print STDERR "Handling $attr on $ref in $phase with [$data]\n";
my $type = ref $ref;
@@ -190,6 +191,8 @@ sub _apply_handler_AH_ {
$attr,
(@$data>1? $data : $data->[0]),
$phase,
+ $filename,
+ $linenum,
);
return 1;
}
@@ -298,19 +301,20 @@ To create a handler, define it as a subroutine with the same name as
the desired attribute, and declare the subroutine itself with the
attribute C<:ATTR>. For example:
- package LoudDecl;
- use Attribute::Handlers;
-
- sub Loud :ATTR {
- my ($package, $symbol, $referent, $attr, $data, $phase) = @_;
- print STDERR
- ref($referent), " ",
- *{$symbol}{NAME}, " ",
- "($referent) ", "was just declared ",
- "and ascribed the ${attr} attribute ",
- "with data ($data)\n",
- "in phase $phase\n";
- }
+ package LoudDecl;
+ use Attribute::Handlers;
+
+ sub Loud :ATTR {
+ my ($package, $symbol, $referent, $attr, $data, $phase, $filename, $linenum) = @_;
+ print STDERR
+ ref($referent), " ",
+ *{$symbol}{NAME}, " ",
+ "($referent) ", "was just declared ",
+ "and ascribed the ${attr} attribute ",
+ "with data ($data)\n",
+ "in phase $phase\n",
+ "in file $filename at line $linenum\n";
+ }
This creates a handler for the attribute C<:Loud> in the class LoudDecl.
Thereafter, any subroutine declared with a C<:Loud> attribute in the class
@@ -346,7 +350,15 @@ any data associated with that attribute;
=item [5]
-the name of the phase in which the handler is being invoked.
+the name of the phase in which the handler is being invoked;
+
+=item [6]
+
+the filename in which the handler is being invoked;
+
+=item [7]
+
+the line number in this file.
=back
diff --git a/lib/Attribute/Handlers/t/linerep.t b/lib/Attribute/Handlers/t/linerep.t
new file mode 100644
index 0000000000..9a2188bf6a
--- /dev/null
+++ b/lib/Attribute/Handlers/t/linerep.t
@@ -0,0 +1,42 @@
+#!perl
+
+BEGIN {
+ if ($ENV{PERL_CORE}) {
+ chdir 't' if -d 't';
+ @INC = '../lib';
+ }
+}
+
+use Test::More tests => 16;
+use Attribute::Handlers;
+
+sub Args : ATTR(CODE) {
+ my ($package, $symbol, $referent, $attr, $data, $phase, $filename, $linenum) = @_;
+ is( $package, 'main', 'package' );
+ is( $symbol, \*foo, 'symbol' );
+ is( $referent, \&foo, 'referent' );
+ is( $attr, 'Args', 'attr' );
+ is( $data, 'bar', 'data' );
+ is( $phase, 'CHECK', 'phase' );
+ is( $filename, __FILE__, 'filename' );
+ is( $linenum, 25, 'linenum' );
+}
+
+sub foo :Args(bar) {}
+
+my $bar :SArgs(grumpf);
+
+sub SArgs : ATTR(SCALAR) {
+ my ($package, $symbol, $referent, $attr, $data, $phase, $filename, $linenum) = @_;
+ is( $package, 'main', 'package' );
+ is( $symbol, 'LEXICAL', 'symbol' );
+ is( $referent, \$bar, 'referent' );
+ is( $attr, 'SArgs', 'attr' );
+ is( $data, 'grumpf', 'data' );
+ is( $phase, 'CHECK', 'phase' );
+ TODO: {
+ local $TODO = "Doesn't work correctly";
+ is( $filename, __FILE__, 'filename' );
+ is( $linenum, 25, 'linenum' );
+ }
+}
diff --git a/lib/Attribute/Handlers/t/multi.t b/lib/Attribute/Handlers/t/multi.t
index db00b1c933..a8156c2550 100644
--- a/lib/Attribute/Handlers/t/multi.t
+++ b/lib/Attribute/Handlers/t/multi.t
@@ -1,3 +1,12 @@
+#!perl
+
+BEGIN {
+ if ($ENV{PERL_CORE}) {
+ chdir 't' if -d 't';
+ @INC = '../lib';
+ }
+}
+
END {print "not ok 1\n" unless $loaded;}
use v5.6.0;
use Attribute::Handlers;