summaryrefslogtreecommitdiffstats
path: root/lib/smartmatch.pm
blob: fd15e03da3ba2b45d502d323ad0fb5867df63421 (plain) (blame)
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
package smartmatch;
use strict;
use warnings;
# ABSTRACT: pluggable smart matching backends

use parent 'DynaLoader';
use B::Hooks::OP::Check;
use B::Hooks::EndOfScope;

sub dl_load_flags { 0x01 }

__PACKAGE__->bootstrap(
    # we need to be careful not to touch $VERSION at compile time, otherwise
    # DynaLoader will assume it's set and check against it, which will cause
    # fail when being run in the checkout without dzil having set the actual
    # $VERSION
    exists $smartmatch::{VERSION}
        ? ${ $smartmatch::{VERSION} } : (),
);

sub import {
    my $package = shift;
    my ($cb) = @_;

    if (!ref($cb)) {
        my $engine = "smartmatch::engine::$cb";
        eval "require $engine; 1"
            or die "Couldn't load smartmatch engine $engine: $@";
        $cb = $engine->can('match') unless ref($cb);
    }

    $^H ||= 0x020000; # HINT_LOCALIZE_HH

    $package->unimport;
    $^H{'smartmatch_cb'} = smartmatch::register($cb);
    on_scope_end { $package->unimport };
}

sub unimport {
    return unless exists $^H{'smartmatch_cb'};
    smartmatch::unregister(delete $^H{'smartmatch_cb'});
}

1;