File: MethodModifier.pm

package info (click to toggle)
libur-perl 0.470%2Bds-3
  • links: PTS, VCS
  • area: main
  • in suites: sid, trixie
  • size: 7,192 kB
  • sloc: perl: 61,814; javascript: 255; xml: 108; sh: 13; makefile: 9
file content (70 lines) | stat: -rw-r--r-- 1,645 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
package UR::Role::MethodModifier;
use strict;
use warnings;

our $VERSION = "0.47"; # UR $VERSION

use Carp;
use Sub::Install;

my $idx = 1;
UR::Object::Type->define(
    class_name => 'UR::Role::MethodModifier',
    is_abstract => 1,
    id_by => [
        idx => { is => 'Integer' },
    ],
    has => [
        name => { is => 'String' },
        code => { is => 'CODE' },
        role_name => { is => 'String' },
        role => { is => 'UR::Role::Prototype', id_by => 'role_name' },
        type => { is => 'String' },
    ],
    id_generator => sub { $idx++ },
);

sub type {
    my $class = ref(shift);
    Carp::croak("Class $class didn't define sub type");
}

sub apply_to_package {
    my($self, $package) = @_;

    my $original_sub = $self->_get_original_sub($package);

    unless ($original_sub) {
        my $name = $self->name;
        Carp::croak(qq(Cannot apply 'before' modifier to $name: Can't locate method "$name" via package $package));
    }

    my $wrapper = $self->create_wrapper_sub($original_sub);
    my $fully_qualified_sub_name = join('::', $package, $self->name);

    $self->_install_sub($package, $wrapper);
}


sub _get_original_sub {
    my($self, $package) = @_;

    my $fully_qualified_subname = join('::', $package, $self->name);

    my $subref = do { no strict 'refs'; exists &$fully_qualified_subname and \&$fully_qualified_subname }
                 || $package->super_can($self->name);

    return $subref;
}

sub _install_sub {
    my($self, $package, $code) = @_;
    Sub::Install::reinstall_sub({
        into => $package,
        as => $self->name,
        code => $code,
    });
}
        

1;