File Coverage

blib/lib/Syntax/Operator/Divides.pm
Criterion Covered Total %
statement 31 36 86.1
branch 9 12 75.0
condition n/a
subroutine 8 10 80.0
pod 0 3 0.0
total 48 61 78.6


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