File Coverage

blib/lib/Syntax/Operator/ExistsOr.pm
Criterion Covered Total %
statement 20 25 80.0
branch 4 8 50.0
condition n/a
subroutine 6 8 75.0
pod 0 3 0.0
total 30 44 68.1


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, 2022-2023 -- leonerd@leonerd.org.uk
5              
6             package Syntax::Operator::ExistsOr 0.02;
7              
8 3     3   466441 use v5.14;
  3         27  
9 3     3   18 use warnings;
  3         6  
  3         75  
10              
11 3     3   17 use Carp;
  3         6  
  3         1065  
12              
13             require XSLoader;
14             XSLoader::load( __PACKAGE__, our $VERSION );
15              
16             =head1 NAME
17              
18             C - an infix operator sensitive to hash element existence
19              
20             =head1 SYNOPSIS
21              
22             On a suitable perl version:
23              
24             use Syntax::Operator::ExistsOr;
25              
26             sub func ( %args ) {
27             my $count = $args{count} \\ 10;
28              
29             say "Count is ", $count // "";
30             }
31              
32             func( count => 20 );
33             func();
34              
35             func( count => undef );
36              
37             =head1 DESCRIPTION
38              
39             This module provides an infix operator that similar to the defined-or C
40             core perl operator, but which cares about hash element existence rather than
41             definedness.
42              
43             Support for custom infix operators was added in the Perl 5.37.x development
44             cycle and is available from development release v5.37.7 onwards, and therefore
45             in Perl v5.38 onwards. The documentation of L
46             describes the situation in more detail.
47              
48             While Perl versions before this do not support custom infix operators, they
49             can still be used via C and hence L.
50             Custom keywords which attempt to parse operator syntax may be able to use
51             these.
52              
53             This module does not provide wrapper functions for the operators, as their
54             inherent short-circuiting behaviour would appear confusing when expressed in
55             function-like syntax.
56              
57             =cut
58              
59             sub import
60             {
61 2     2   16 my $pkg = shift;
62 2         11 my $caller = caller;
63              
64 2         9 $pkg->import_into( $caller, @_ );
65             }
66              
67             sub unimport
68             {
69 0     0   0 my $pkg = shift;
70 0         0 my $caller = caller;
71              
72 0         0 $pkg->unimport_into( $caller, @_ );
73             }
74              
75 2     2 0 6 sub import_into { shift->apply( 1, @_ ) }
76 0     0 0 0 sub unimport_into { shift->apply( 0, @_ ) }
77              
78             sub apply
79             {
80 2     2 0 3 my $pkg = shift;
81 2         5 my ( $on, $caller, @syms ) = @_;
82              
83 2 50       9 @syms or @syms = qw( existsor );
84              
85 2         6 my %syms = map { $_ => 1 } @syms;
  2         8  
86 2 50       13 if( delete $syms{existsor} ) {
87             $on ? $^H{"Syntax::Operator::ExistsOr/existsor"}++
88 2 50       15 : delete $^H{"Syntax::Operator::ExistsOr/existsor"};
89             }
90              
91 2 50       99 croak "Unrecognised import symbols @{[ keys %syms ]}" if keys %syms;
  0            
92             }
93              
94             =head1 OPERATORS
95              
96             =head2 \\
97              
98             my $value = $hash{$key} \\ EXPR;
99              
100             The lefthand operand must be a hash element access (i.e. C<$hash{$key}> or
101             C<< $href->{$key} >> for some expressions yielding a key and a hashref).
102              
103             If the hash contains the given key then the operator yields its value (even if
104             that value is C). If the key does not exist in the hash, then the
105             righthand operand will be evaluated in scalar context and its value returned.
106              
107             This is a short-circuiting operator; if the hash does contain the key then the
108             righthand side expression is not evaluated at all.
109              
110             This operator parses at the same precedence level as the logical-or operators
111             (C<||> and C).
112              
113             =head2 existsor
114              
115             do {
116             $hash{$key} existsor EXPR;
117             };
118              
119             Similar to the C<\\> operator but parses at the same level as the
120             low-precedence or operator (C). This is unlikely to be very useful, as
121             normally C would be used for value-less control flow. Such a potential use
122             for this operator would be neater written
123              
124             exists $hash{$key} or EXPR;
125              
126             It is included largely for completeness.
127              
128             =cut
129              
130             =head1 AUTHOR
131              
132             Paul Evans
133              
134             =cut
135              
136             0x55AA;