diff options
author | David Feldman <david.feldman@tudor.com> | 2006-10-25 12:34:26 -0400 |
---|---|---|
committer | Rafael Garcia-Suarez <rgarciasuarez@gmail.com> | 2006-11-09 15:58:11 +0000 |
commit | cab6c672e9819e2fc0a67e60c3b18ff6c0385dac (patch) | |
tree | ac806fade85e470a26c9996ef1051ac5e2eb53ee /lib/Attribute | |
parent | 4bd7b839c96352aa075f714f4c1aaa963c29018e (diff) | |
download | perl-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.pm | 46 | ||||
-rw-r--r-- | lib/Attribute/Handlers/t/linerep.t | 42 | ||||
-rw-r--r-- | lib/Attribute/Handlers/t/multi.t | 9 |
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; |