File Coverage

blib/lib/Syntax/Operator/ExistsOr.pm
Criterion Covered Total %
statement 18 19 94.7
branch 3 6 50.0
condition n/a
subroutine 5 5 100.0
pod 0 1 0.0
total 26 31 83.8


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 -- leonerd@leonerd.org.uk
5              
6             package Syntax::Operator::ExistsOr 0.01;
7              
8 3     3   135328 use v5.14;
  3         31  
9 3     3   16 use warnings;
  3         6  
  3         75  
10              
11 3     3   14 use Carp;
  3         6  
  3         813  
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             Current stable versions of perl do not directly support custom infix
44             operators, but the ability was added in the 5.37.x development cycle and is
45             available from perl v5.37.7 onwards. The documentation of L
46             describes the situation in more detail. This module is therefore I
47             entirely useless on stable perl builds. While the regular parser does not
48             support custom infix operators, they are supported via C and
49             hence L, and so custom keywords which attempt to parse
50             operator syntax may be able to use it.
51              
52             This module does not provide wrapper functions for the operators, as their
53             inherent short-circuiting behaviour would appear confusing when expressed in
54             function-like syntax.
55              
56             =cut
57              
58             =head1 OPERATORS
59              
60             =head2 \\
61              
62             my $value = $hash{$key} \\ EXPR;
63              
64             The lefthand operand must be a hash element access (i.e. C<$hash{$key}> or
65             C<< $href->{$key} >> for some expressions yielding a key and a hashref).
66              
67             If the hash contains the given key then the operator yields its value (even if
68             that value is C). If the key does not exist in the hash, then the
69             righthand operand will be evaluated in scalar context and its value returned.
70              
71             This is a short-circuiting operator; if the hash does contain the key then the
72             righthand side expression is not evaluated at all.
73              
74             This operator parses at the same precedence level as the logical-or operators
75             (C<||> and C).
76              
77             =head2 existsor
78              
79             do {
80             $hash{$key} existsor EXPR;
81             };
82              
83             Similar to the C<\\> operator but parses at the same level as the
84             low-precedence or operator (C). This is unlikely to be very useful, as
85             normally C would be used for value-less control flow. Such a potential use
86             for this operator would be neater written
87              
88             exists $hash{$key} or EXPR;
89              
90             It is included largely for completeness.
91              
92             =cut
93              
94             sub import
95             {
96 3     3   25 my $class = shift;
97 3         6 my $caller = caller;
98              
99 3         12 $class->import_into( $caller, @_ );
100             }
101              
102             sub import_into
103             {
104 3     3 0 6 my $class = shift;
105 3         7 my ( $caller, @syms ) = @_;
106              
107 3 50       15 @syms or @syms = qw( existsor );
108              
109 3         7 my %syms = map { $_ => 1 } @syms;
  3         12  
110 3 50       28 $^H{"Syntax::Operator::ExistsOr/existsor"}++ if delete $syms{existsor};
111              
112 3 50       106 croak "Unrecognised import symbols @{[ keys %syms ]}" if keys %syms;
  0            
113             }
114              
115             =head1 AUTHOR
116              
117             Paul Evans
118              
119             =cut
120              
121             0x55AA;