root/lang/perl/Attribute-Overload/trunk/lib/Attribute/Overload.pm @ 9732

Revision 9732, 2.3 kB (checked in by hanekomu, 5 years ago)

r6030@nbgr: marcel | 2008-04-18 16:10:28 +0200
lang/perl/Attribute-Overload: initial commit

Line 
1package Attribute::Overload;
2
3use warnings;
4use strict;
5use Attribute::Handlers;
6
7our $VERSION = '0.05';
8
9
10# RAWDATA to get '""' as such;
11# CODE would interpret it as empty string and return nothing
12
13sub UNIVERSAL::Overload : ATTR(CODE,RAWDATA) {
14        my ($pkg, $symbol, $data) = @_[0,1,4];
15        our %overload;
16        for (ref $data eq 'ARRAY' ? @$data : $data) {
17                die "Too late to overload constant $_ in CHECK for $symbol\n"
18                    if /^(integer|float|binary|qr?)$/;
19                s!\"\"!""!g;
20                $overload{$pkg}{$_} = *{$symbol}{NAME};
21        }
22}
23
24
25sub INIT {
26        # only eval here, because multiple overloaded subs must only
27        # trigger one 'use overload' statement
28        our %overload;
29
30        my $code;
31
32        while (my ($pkg, $pkgdef) = each %overload) {
33                my (@code, @constcode);
34                while (my ($op, $sub) = each %$pkgdef) {
35                        if ($op =~ /^(integer|float|binary|qr?)$/) {
36                                push @constcode => "$op => \\&$sub";
37                        } else {
38                                push @code => "'$op' => \\&$sub";
39                        }
40                }
41                next unless @code || @constcode;  # huh? no defs?
42                $code .= "package $pkg;\n";
43                $code .= "use overload\n" . join(",\n" => @code) . ";\n"
44                    if @code;
45
46                # Note: the following doesn't do anything, since import()
47                # is called at BEGIN via use(), but attributes are only
48                # evaluated during CHECK. So it's commented out for now.
49
50                # $code .= "BEGIN { sub import { overload::constant (\n" .
51                #     join(",\n" => @constcode) . ")}};\n" if @constcode;
52        }
53
54        eval $code if $code;
55        die $@ if $@;
56}
57
58
591;
60
61
62__END__
63
64{% USE p = PodGenerated %}
65
66=head1 NAME
67
68Attribute::Overload - Attribute that makes overloading easier
69
70=head1 SYNOPSIS
71
72  use Attribute::Overload;
73  sub add : Overload(+) { ... }
74
75=head1 DESCRIPTION
76
77The C<Overload> attribute, when used on a subroutine, declares that subroutine
78as the handler in the current package for the operation(s) indicated by the
79attribute options. Thus it frees you from the implementation details of how to
80declare overloads and keeps the definitions where they belong, with the
81operation handlers.
82
83For details of which operations can be overloaded and what the overloading
84function gets passed see the L<overload> manpage.
85
86Note that you can't overload constants this way, since this has to happen
87during BEGIN time, but attributes are only evaluated at CHECK time, at least
88as far as L<Attribute::Handlers> is concerned.
89
90{% PROCESS standard_pod %}
91
92=cut
93
Note: See TracBrowser for help on using the browser.