Attribute-Handlers

 view release on metacpan or  search on metacpan

lib/Attribute/Handlers.pm  view on Meta::CPAN

				# CHECK it's for a lexical, so make sure
				# it didn't want to run anything later
			
				local $Carp::CarpLevel = 2;
				carp "Won't be able to apply END handler"
					if $phase{$handler}{END};
			}
			else {
				push @declarations, $decl
			}
		}
		$_ = undef;
	    }
	    return grep {defined && !/$builtin/} @attrs;
	}
}

{
    no strict 'refs';
    *{"Attribute::Handlers::UNIVERSAL::MODIFY_${_}_ATTRIBUTES"} =
	_gen_handler_AH_ foreach @{$validtype{ANY}};
}
push @UNIVERSAL::ISA, 'Attribute::Handlers::UNIVERSAL'
       unless grep /^Attribute::Handlers::UNIVERSAL$/, @UNIVERSAL::ISA;

sub _apply_handler_AH_ {
	my ($declaration, $phase) = @_;
	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"
            if $debug;
	my $type = ref $ref;
	my $handler = "_ATTR_${type}_${attr}";
	my $sym = findsym($pkg, $ref);
	$sym ||= $type eq 'CODE' ? 'ANON' : 'LEXICAL';
	no warnings;
	if (!$raw && defined($data)) {
	    if ($data ne '') {
                # keeping the minimum amount of code inside the eval string
                # makes debugging perl internals issues with this logic easier.
                my $code= "package $pkg; my \$ref= [$data]; \$data= \$ref; 1";
                print STDERR "Evaling: '$code'\n"
                    if $debug;
                local $SIG{__WARN__} = sub{ die };
                no strict;
                no warnings;
                # Note in production we do not need to use the return value from
                # the eval or even consult $@ after the eval - if the evaled code
                # compiles and runs successfully then it will update $data with
                # the compiled form, if it fails then $data stays unchanged. The
                # return value and $@ are only used for debugging purposes.
                # IOW we could just replace the following with eval($code);
                eval($code) or do {
                    print STDERR "Eval failed: $@"
                        if $debug;
                };
	    }
	    else { $data = undef }
	}

        # now call the handler with the $data decoded (maybe)
	$pkg->$handler($sym,
		       (ref $sym eq 'GLOB' ? *{$sym}{ref $ref}||$ref : $ref),
		       $attr,
		       $data,
		       $phase,
		       $filename,
		       $linenum,
		      );
	return 1;
}

{
        no warnings 'void';
        CHECK {
                $global_phase++;
                _resolve_lastattr if _delayed_name_resolution;
                foreach my $decl (@declarations) {
                        _apply_handler_AH_($decl, 'CHECK');
                }
        }

        INIT {
                $global_phase++;
                foreach my $decl (@declarations) {
                        _apply_handler_AH_($decl, 'INIT');
                }
        }
}

END {
        $global_phase++;
        foreach my $decl (@declarations) {
                _apply_handler_AH_($decl, 'END');
        }
}

1;
__END__

=head1 NAME

Attribute::Handlers - Simpler definition of attribute handlers

=head1 VERSION

This document describes version 1.03 of Attribute::Handlers.

=head1 SYNOPSIS

    package MyClass;
    require 5.006;
    use Attribute::Handlers;
    no warnings 'redefine';


    sub Good : ATTR(SCALAR) {
	my ($package, $symbol, $referent, $attr, $data) = @_;

	# Invoked for any scalar variable with a :Good attribute,
	# provided the variable was declared in MyClass (or



( run in 0.622 second using v1.01-cache-2.11-cpan-13bb782fe5a )