File Coverage

blib/lib/Map/Metro/Hook.pm
Criterion Covered Total %
statement 73 78 93.5
branch 0 4 0.0
condition n/a
subroutine 8 9 88.8
pod n/a
total 81 91 89.0


line stmt bran cond sub pod time code
1 1     1   5 use Map::Metro::Standard::Moops;
  1         3  
  1         10  
2 1     1   2504 use strict;
  1         3  
  1         25  
3 1     1   7 use warnings;
  1         2  
  1         62  
4              
5             our $VERSION = '0.2300'; # VERSION
6             # PODNAME: Map::Metro::Hook
7             # ABSTRACT: Hook into Map::Metro
8              
9 1     1   1663 class Map::Metro::Hook {
  1     1   34  
  1     1   7  
  1         2  
  1         62  
  1         5  
  1         2  
  1         9  
  1         254  
  1         2  
  1         9  
  1         61  
  1         3  
  1         52  
  1         6  
  1         2  
  1         106  
  1         35  
  1         6  
  1         2  
  1         8  
  1         4634  
  1         2  
  1         9  
  1         6745  
  1         3  
  1         11  
  1         4522  
  1         2  
  1         13  
  1         97  
  1         2  
  1         11  
  1         224  
  1         2  
  1         10  
  1         1366  
  1         2  
  1         10  
  1         6380  
  1         3  
  1         5  
  1         3  
  1         32  
  1         7  
  1         2  
  1         62  
  1         6  
  1         2  
  1         151  
  1         10  
  1         5347  
  1         22  
  1         236  
  0            
10              
11 1     1   16137 use Type::Tiny::Enum;
  1         1714  
  1         91  
12              
13 1         17 has event => (
14             is => 'ro',
15             isa => Type::Tiny::Enum->new(values => [qw/
16             before_add_station
17             before_start_routing
18             before_add_routing
19             /]),
20             );
21 1         4965 has action => (
22             is => 'ro',
23             isa => CodeRef,
24             );
25 1         4167 has plugin => (
26             is => 'ro',
27             );
28              
29 1 0   1   2231 method perform(@args) {
  1 0   0   4  
  1         145  
  1         3949  
  0            
  0            
  0            
30 0           $self->action(@args);
31             }
32              
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.2300, released 2016-01-14.
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             ...C<use Moops;>
104              
105             ...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.
106              
107             =head3 Example
108              
109             The C<StreamStations> hook mentioned in the synopsis, and included in this distribution, looks like this:
110              
111             use feature ':5.16';
112              
113             package Map::Metro::Plugin::Hook::StreamStations {
114              
115             use Moose;
116             use Types::Standard -types;
117              
118             has station_names => (
119             is => 'rw',
120             isa => ArrayRef,
121             traits => ['Array'],
122             handles => {
123             add_station_name => 'push',
124             all_station_names => 'elements',
125             get_station_name => 'get',
126             },
127             );
128              
129             sub register {
130             before_add_station => sub {
131             my $self = shift;
132             my $station = shift;
133              
134             say $station->name;
135             $self->add_station_name($station->name);
136             };
137             }
138             }
139              
140             1;
141              
142             It does two things, as stations are parsed from the map file and the C<before_add_station> method is executed for every station:
143              
144             * It prints all station names.
145              
146             * It adds all station names to the C<station_names> attribute.
147              
148             So if you instantiate your graph like this:
149              
150             my $graph = Map::Metro->new('Helsinki', hooks => ['Helsinki::Swedish', 'StreamStations'])->parse;
151              
152             You can then access this C<station_names> attribute like this:
153              
154             my $station_streamer = $graph->get_plugin('StreamStations');
155              
156             my @station_names = $station_streamer->all_station_names;
157             my $special_station = $station_streamer->get_station_name(7);
158              
159             =head1 SOURCE
160              
161             L<https://github.com/Csson/p5-Map-Metro>
162              
163             =head1 HOMEPAGE
164              
165             L<https://metacpan.org/release/Map-Metro>
166              
167             =head1 AUTHOR
168              
169             Erik Carlsson <info@code301.com>
170              
171             =head1 COPYRIGHT AND LICENSE
172              
173             This software is copyright (c) 2016 by Erik Carlsson.
174              
175             This is free software; you can redistribute it and/or modify it under
176             the same terms as the Perl 5 programming language system itself.
177              
178             =cut