File Coverage

blib/lib/Map/Metro/Hook.pm
Criterion Covered Total %
statement 14 16 87.5
branch n/a
condition n/a
subroutine 5 6 83.3
pod 0 1 0.0
total 19 23 82.6


line stmt bran cond sub pod time code
1 2     2   16 use 5.10.0;
  2         4  
2 2     2   8 use strict;
  2         2  
  2         35  
3 2     2   6 use warnings;
  2         2  
  2         87  
4              
5             package Map::Metro::Hook;
6              
7             # ABSTRACT: Hook into Map::Metro
8             our $AUTHORITY = 'cpan:CSSON'; # AUTHORITY
9             our $VERSION = '0.2405';
10              
11 2     2   6 use Map::Metro::Elk;
  2         3  
  2         10  
12 2     2   2385 use Types::Standard qw/CodeRef Enum/;
  2         3  
  2         10  
13              
14             has event => (
15             is => 'ro',
16             isa => Enum[qw/
17             before_add_station
18             before_start_routing
19             before_add_routing
20             /],
21             );
22             has action => (
23             is => 'ro',
24             isa => CodeRef,
25             );
26             has plugin => (
27             is => 'ro',
28             );
29              
30             sub perform {
31 0     0 0   my $self = shift;
32 0           $self->action(@_);
33             }
34              
35             1;
36              
37             __END__
38              
39             =pod
40              
41             =encoding UTF-8
42              
43             =head1 NAME
44              
45             Map::Metro::Hook - Hook into Map::Metro
46              
47             =head1 VERSION
48              
49             Version 0.2405, released 2016-07-23.
50              
51             =head1 SYNOPSIS
52              
53             use Map::Metro;
54              
55             my $graph = Map::Metro->new('Helsinki', hooks => ['Helsinki::Swedish'])->parse;
56              
57             # Now all station names are in Swedish
58              
59             my $graph2 = Map::Metro->new('Helsinki', hooks => ['Helsinki::Swedish', 'StreamStations'])->parse;
60              
61             # Station names are in Swedish, as before, but they are also printed as they are
62             # added from the map file. See more on StreamStations below.
63              
64             =head1 DESCRIPTION
65              
66             Hooks are a powerful way to interact (and change) Map::Metro while it is building the network or finding routes.
67              
68             Hooks are implemented as classes in the C<Map::Metro::Plugin::Hook> namespace.
69              
70             =head2 Hooks
71              
72             All hooks get the hook class instance as its first parameter, and can beyond that receive further parameters depending on where they hook into C<Map::Metro>.
73              
74             There are currently two hooks (events) available:
75              
76             =head3 before_add_station($plugin, $station)
77              
78             C<$station>
79              
80             The L<Map::Metro::Graph::Station> object that is about to be added.
81              
82             This event fires right before the station is added to the L<Map::Metro::Graph> object. Especially useful for enabling
83             translations of station names.
84              
85             =head3 before_add_routing($plugin, $routing)
86              
87             C<$routing>
88              
89             The L<Map::Metro::Graph::Routing> object that is about to be added.
90              
91             This event fires after a routing has been completed (all routes between two L<Stations|Map::Metro::Graph::Station> has been found).
92              
93             This is useful for printing routings as they are found rather than waiting until all routings are found.
94              
95             Used by the bundled L<PrettyPrinter|Map::Metro::Plugin::Hook::PrettyPrinter> hook. That also serves as a good template for customized hooks.
96              
97             =head2 Custom hooks
98              
99             Two things are necessary for a hook class. It must...
100              
101             ...live in the C<Map::Metro::Plugin::Hook> namespace.
102              
103             ...have a C<register> method, that returns a hash where the key is the hook type and the value the sub routine that should be executed when the event is fired. Since register returns a hash, one C<Plugin::Hook> class can hook into more than one event.
104              
105             =head3 Example
106              
107             Take a look at L<Map::Metro::Plugin::Hook::StreamStations>.
108              
109             The C<StreamStations> hook mentioned in the synopsis, and included in this distribution, looks like this:
110              
111             package Map::Metro::Plugin::Hook::StreamStations;
112              
113             use Moose;
114             use Types::Standard -types;
115              
116             has station_names => (
117             is => 'rw',
118             isa => ArrayRef,
119             traits => ['Array'],
120             handles => {
121             add_station_name => 'push',
122             all_station_names => 'elements',
123             get_station_name => 'get',
124             },
125             );
126              
127             sub register {
128             before_add_station => sub {
129             my $self = shift;
130             my $station = shift;
131              
132             say $station->name;
133             $self->add_station_name($station->name);
134             };
135             }
136             }
137              
138             1;
139              
140             It does two things, as stations are parsed from the map file and the C<before_add_station> method is executed for every station:
141              
142             * It prints all station names.
143              
144             * It adds all station names to the C<station_names> attribute.
145              
146             So if you instantiate your graph like this:
147              
148             my $graph = Map::Metro->new('Helsinki', hooks => ['Helsinki::Swedish', 'StreamStations'])->parse;
149              
150             You can then access this C<station_names> attribute like this:
151              
152             my $station_streamer = $graph->get_plugin('StreamStations');
153              
154             my @station_names = $station_streamer->all_station_names;
155             my $special_station = $station_streamer->get_station_name(7);
156              
157             =head1 SOURCE
158              
159             L<https://github.com/Csson/p5-Map-Metro>
160              
161             =head1 HOMEPAGE
162              
163             L<https://metacpan.org/release/Map-Metro>
164              
165             =head1 AUTHOR
166              
167             Erik Carlsson <info@code301.com>
168              
169             =head1 COPYRIGHT AND LICENSE
170              
171             This software is copyright (c) 2016 by Erik Carlsson.
172              
173             This is free software; you can redistribute it and/or modify it under
174             the same terms as the Perl 5 programming language system itself.
175              
176             =cut