File Coverage

blib/lib/Syntax/Operator/Divides.pm
Criterion Covered Total %
statement 35 36 97.2
branch 7 8 87.5
condition 1 3 33.3
subroutine 10 10 100.0
pod 0 3 0.0
total 53 60 88.3


line stmt bran cond sub pod time code
1             # You may distribute under the terms of either the GNU General Public License
2             # or the Artistic License (the same terms as Perl itself)
3             #
4             # (C) Paul Evans, 2021-2024 -- leonerd@leonerd.org.uk
5              
6             package Syntax::Operator::Divides 0.08;
7              
8 3     3   1046123 use v5.14;
  3         11  
9 3     3   19 use warnings;
  3         5  
  3         164  
10              
11 3     3   17 use Carp;
  3         5  
  3         269  
12              
13 3     3   1630 use meta 0.003_002;
  3         3304  
  3         142  
14 3     3   36 no warnings 'meta::experimental';
  3         5  
  3         1373  
15              
16             require XSLoader;
17             XSLoader::load( __PACKAGE__, our $VERSION );
18              
19             =head1 NAME
20              
21             C - an infix operator for division test
22              
23             =head1 SYNOPSIS
24              
25             On Perl v5.38 or later:
26              
27             use Syntax::Operator::Divides;
28              
29             say "Multiple of 10" if $x %% 10;
30              
31             Or via L on Perl v5.14 or later:
32              
33             use v5.14;
34             use Syntax::Keyword::Match;
35             use Syntax::Operator::Divides;
36              
37             foreach ( 1 .. 100 ) {
38             match( $_ : %% ) {
39             case(15) { say "FizzBuzz" }
40             case(3) { say "Fizz" }
41             case(5) { say "Buzz" }
42             default { say $_ }
43             }
44             }
45              
46             =head1 DESCRIPTION
47              
48             This module provides an infix operator that implements an integer divides test
49             which returns true if the lefthand operand is a whole multiple of the
50             righthand.
51              
52             Support for custom infix operators was added in the Perl 5.37.x development
53             cycle and is available from development release v5.37.7 onwards, and therefore
54             in Perl v5.38 onwards. The documentation of L
55             describes the situation in more detail.
56              
57             While Perl versions before this do not support custom infix operators, they
58             can still be used via C and hence L.
59             Custom keywords which attempt to parse operator syntax may be able to use
60             these. One such module is L; see the SYNOPSIS example
61             given above.
62              
63             =cut
64              
65             sub import
66             {
67 2     2   17 my $pkg = shift;
68 2         7 my $caller = caller;
69              
70 2         9 $pkg->import_into( $caller, @_ );
71             }
72              
73             sub unimport
74             {
75 2     2   88 my $pkg = shift;
76 2         5 my $caller = caller;
77              
78 2         8 $pkg->unimport_into( $caller, @_ );
79             }
80              
81 2     2 0 6 sub import_into { shift->apply( 1, @_ ) }
82 2     2 0 5 sub unimport_into { shift->apply( 0, @_ ) }
83              
84             sub apply
85             {
86 4     4 0 9 my $pkg = shift;
87 4         10 my ( $on, $caller, @syms ) = @_;
88              
89 4 100       16 @syms or @syms = qw( %% );
90              
91 4         15 $pkg->XS::Parse::Infix::apply_infix( $on, \@syms, qw( %% ) );
92              
93 4         122 my %syms = map { $_ => 1 } @syms;
  2         3  
94 4         7 my $callerpkg;
95              
96 4         9 foreach (qw( is_divisor )) {
97 4 100       11 next unless delete $syms{$_};
98              
99 2   33     54 $callerpkg //= meta::package->get( $caller );
100              
101 2 100       8 $on ? $callerpkg->add_symbol( '&'.$_ => \&{$_} )
  1         7  
102             : $callerpkg->remove_symbol( '&'.$_ );
103             }
104              
105 4 50       3650 croak "Unrecognised import symbols @{[ keys %syms ]}" if keys %syms;
  0            
106             }
107              
108             =head1 OPERATORS
109              
110             =head2 %%
111              
112             my $divides = $numerator %% $denominator;
113              
114             Yields true if the numerator operand is a whole integer multiple of the
115             denominator. This is implemented by using the C<%> modulus operator and
116             testing if the remainder is zero.
117              
118             =cut
119              
120             =head1 FUNCTIONS
121              
122             As a convenience, the following functions may be imported which implement the
123             same behaviour as the infix operators, though are accessed via regular
124             function call syntax.
125              
126             These wrapper functions are implemented using L, and thus
127             have an optimising call-checker attached to them. In most cases, code which
128             calls them should not in fact have the full runtime overhead of a function
129             call because the underlying test operator will get inlined into the calling
130             code at compiletime. In effect, code calling these functions should run with
131             the same performance as code using the infix operators directly.
132              
133             =head2 is_divisor
134              
135             my $divides = is_divisor( $numerator, $denominator );
136              
137             A function version of the L operator.
138              
139             =cut
140              
141             =head1 AUTHOR
142              
143             Paul Evans
144              
145             =cut
146              
147             0x55AA;