File Coverage

blib/lib/Syntax/Keyword/Inplace.pm
Criterion Covered Total %
statement 23 25 92.0
branch 1 2 50.0
condition n/a
subroutine 10 10 100.0
pod 0 3 0.0
total 34 40 85.0


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::Keyword::Inplace 0.02;
7              
8 4     4   699814 use v5.14;
  4         42  
9 4     4   21 use warnings;
  4         8  
  4         100  
10              
11 4     4   23 use Carp;
  4         11  
  4         1556  
12              
13             require XSLoader;
14             XSLoader::load( __PACKAGE__, our $VERSION );
15              
16             =head1 NAME
17              
18             C - syntax for making inplace changes to variables
19              
20             =head1 SYNOPSIS
21              
22             use Syntax::Keyword::Inplace;
23              
24             my $var = "some value here";
25             inplace uc $var; # equivalent to $var = uc $var;
26              
27             print $var; # prints "SOME VALUE HERE"
28              
29             =head1 DESCRIPTION
30              
31             This module provides a syntax plugin that implements a single keyword,
32             C, which acts on function calls (or function-like perl operators)
33             to make them modify the target expression.
34              
35             Perl has a large number of function-like operators that look at a single
36             expression argument and return some new value based on it. Sometimes the
37             result of calling one of these is immediately assigned back into the same
38             variable again, in code that looks like C<$var = func($var)>. It is for these
39             situations where this module is intended to apply.
40              
41             =cut
42              
43             =head1 KEYWORDS
44              
45             =head2 inplace
46              
47             inplace FUNC( EXPR )
48              
49             The C keyword modifies the behaviour of the following expression,
50             which must be a function call or function-like core perl operator, which takes
51             exactly one argument. That single argument must be valid as an lvalue (i.e.
52             the target of an assignment). At runtime the function is called on that
53             argument expression and the result of the function call is stored back into
54             that expression.
55              
56             my $var = ...;
57             inplace foo( $var ); # equivalent to $var = foo( $var )
58              
59             If the expression is more complex than a single variable directly, then any
60             side-effects involved in generating it only happen once.
61              
62             inplace foo( $hash{some_function_call()} );
63              
64             # equivalent to
65             # my $tmp_key = some_function_call();
66             # $hash{$tmp_key} = foo( $hash{$tmp_key} );
67              
68             =cut
69              
70             sub import
71             {
72 3     3   27 my $pkg = shift;
73 3         7 my $caller = caller;
74              
75 3         16 $pkg->import_into( $caller, @_ );
76             }
77              
78             sub unimport
79             {
80 1     1   10 my $pkg = shift;
81 1         3 my $caller = caller;
82              
83 1         4 $pkg->unimport_into( $caller, @_ );
84             }
85              
86 3     3 0 21 sub import_into { shift->apply( sub { $^H{ $_[0] }++ }, @_ ) }
  3     3   16  
87 1     1 0 5 sub unimport_into { shift->apply( sub { delete $^H{ $_[0] } }, @_ ) }
  1     1   6  
88              
89             sub apply
90             {
91 4     4 0 8 my $pkg = shift;
92 4         9 my ( $cb, $caller, @syms ) = @_;
93              
94 4         11 my %syms = map { $_ => 1 } @syms;
  0         0  
95 4         12 $cb->( "Syntax::Keyword::Inplace/inplace" );
96              
97 4 50       4224 croak "Unrecognised import symbols @{[ keys %syms ]}" if keys %syms;
  0            
98             }
99              
100             =head1 AUTHOR
101              
102             Paul Evans
103              
104             =cut
105              
106             0x55AA;