summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorgregor herrmann <gregoa@debian.org>2022-02-25 17:59:52 +0100
committergregor herrmann <gregoa@debian.org>2022-02-25 17:59:52 +0100
commit8c0bd13491099dbc5a70ba6e48163dadb1140272 (patch)
treee06dea40e3e314ad709fdb72f3bd06a52cf32762
parent2d128481b81ddb45f7f5e11984dce3343ec64532 (diff)
parent414d8c5c22fc3d54f5782057427b3f00d42d2c8a (diff)
Update upstream source from tag 'upstream/0.05'
Update to upstream version '0.05' with Debian dir 6803215c84af51592b849e1fbcfaabd3b10d17e1
-rw-r--r--Build.PL10
-rw-r--r--Changes4
-rw-r--r--LICENSE18
-rw-r--r--MANIFEST9
-rw-r--r--META.json8
-rw-r--r--META.yml6
-rw-r--r--README53
-rw-r--r--lib/Feature/Compat/Try.pm61
-rw-r--r--t/03trycatchfinally.t42
-rw-r--r--t/12return.t15
-rw-r--r--t/16final-expr.t6
11 files changed, 185 insertions, 47 deletions
diff --git a/Build.PL b/Build.PL
index 4deb0cb..a5391bd 100644
--- a/Build.PL
+++ b/Build.PL
@@ -7,17 +7,13 @@ my %REQUIRES_PERL = (
);
my %REQUIRES_SKT = (
- 'Syntax::Keyword::Try' => '0.22',
+ 'Syntax::Keyword::Try' => '0.27',
);
use feature ();
my $HAVE_FEATURE_TRY = do {
- # %feature::feature was only added on 5.16, but that's fine. If we're
- # running on 5.14 this definitely won't be define()ed anyway. Looking at a
- # package var is safe even under strict, we'll just get a "used once only"
- # typo warning. We can quiet it.
- no warnings 'once';
- defined $feature::feature{try};
+ # Core's use feature 'try' only supports 'finally' since 5.35.8
+ $] >= 5.035008
};
printf "Using %s\n",
diff --git a/Changes b/Changes
index 3ce7349..def7e46 100644
--- a/Changes
+++ b/Changes
@@ -1,5 +1,9 @@
Revision history for Feature-Compat-Try
+0.05 2022-02-20
+ [CHANGES]
+ * Support `finally {}` blocks on perl 5.35.9 or via SKT 0.27
+
0.04 2021-03-27
[CHANGES]
* Unit tests and documentation of the handling of the final-value
diff --git a/LICENSE b/LICENSE
index f15476d..7f7fca7 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,4 +1,4 @@
-This software is copyright (c) 2021 by Paul Evans <leonerd@leonerd.org.uk>.
+This software is copyright (c) 2022 by Paul Evans <leonerd@leonerd.org.uk>.
This is free software; you can redistribute it and/or modify it under
the same terms as the Perl 5 programming language system itself.
@@ -12,7 +12,7 @@ b) the "Artistic License"
--- The GNU General Public License, Version 1, February 1989 ---
-This software is Copyright (c) 2021 by Paul Evans <leonerd@leonerd.org.uk>.
+This software is Copyright (c) 2022 by Paul Evans <leonerd@leonerd.org.uk>.
This is free software, licensed under:
@@ -272,7 +272,7 @@ That's all there is to it!
--- The Artistic License 1.0 ---
-This software is Copyright (c) 2021 by Paul Evans <leonerd@leonerd.org.uk>.
+This software is Copyright (c) 2022 by Paul Evans <leonerd@leonerd.org.uk>.
This is free software, licensed under:
@@ -292,21 +292,21 @@ Definitions:
- "Package" refers to the collection of files distributed by the Copyright
Holder, and derivatives of that collection of files created through
- textual modification.
+ textual modification.
- "Standard Version" refers to such a Package if it has not been modified,
or has been modified in accordance with the wishes of the Copyright
- Holder.
+ Holder.
- "Copyright Holder" is whoever is named in the copyright or copyrights for
- the package.
+ the package.
- "You" is you, if you're thinking about copying or distributing this Package.
- "Reasonable copying fee" is whatever you can justify on the basis of media
cost, duplication charges, time of people involved, and so on. (You will
not be required to justify it to the Copyright Holder, but only to the
- computing community at large as a market that must bear the fee.)
+ computing community at large as a market that must bear the fee.)
- "Freely Available" means that no fee is charged for the item itself, though
there may be fees involved in handling the item. It also means that
recipients of the item may redistribute it under the same conditions they
- received it.
+ received it.
1. You may make and give away verbatim copies of the source form of the
Standard Version of this Package without restriction, provided that you
@@ -373,7 +373,7 @@ products derived from this software without specific prior written permission.
9. THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
-MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
The End
diff --git a/MANIFEST b/MANIFEST
index 5ea5ca5..50670ca 100644
--- a/MANIFEST
+++ b/MANIFEST
@@ -1,13 +1,10 @@
Build.PL
Changes
lib/Feature/Compat/Try.pm
-LICENSE
MANIFEST This list of files
-META.json
-META.yml
-README
t/00use.t
t/01trycatch.t
+t/03trycatchfinally.t
t/10snail.t
t/11loop.t
t/12return.t
@@ -16,3 +13,7 @@ t/15context.t
t/16final-expr.t
t/80await+try.t
t/99pod.t
+README
+LICENSE
+META.yml
+META.json
diff --git a/META.json b/META.json
index 34f4e3e..44c4760 100644
--- a/META.json
+++ b/META.json
@@ -21,7 +21,7 @@
},
"runtime" : {
"requires" : {
- "Syntax::Keyword::Try" : "0.22",
+ "Syntax::Keyword::Try" : "0.27",
"perl" : "5.014"
}
},
@@ -34,7 +34,7 @@
"provides" : {
"Feature::Compat::Try" : {
"file" : "lib/Feature/Compat/Try.pm",
- "version" : "0.04"
+ "version" : "0.05"
}
},
"release_status" : "stable",
@@ -43,6 +43,6 @@
"http://dev.perl.org/licenses/"
]
},
- "version" : "0.04",
- "x_serialization_backend" : "JSON::PP version 4.05"
+ "version" : "0.05",
+ "x_serialization_backend" : "JSON::PP version 4.06"
}
diff --git a/META.yml b/META.yml
index 0d8176a..dfc0a84 100644
--- a/META.yml
+++ b/META.yml
@@ -16,11 +16,11 @@ name: Feature-Compat-Try
provides:
Feature::Compat::Try:
file: lib/Feature/Compat/Try.pm
- version: '0.04'
+ version: '0.05'
requires:
- Syntax::Keyword::Try: '0.22'
+ Syntax::Keyword::Try: '0.27'
perl: '5.014'
resources:
license: http://dev.perl.org/licenses/
-version: '0.04'
+version: '0.05'
x_serialization_backend: 'CPAN::Meta::YAML version 0.018'
diff --git a/README b/README
index dda266e..7e54a39 100644
--- a/README
+++ b/README
@@ -20,11 +20,11 @@ SYNOPSIS
DESCRIPTION
- This module is written in preparation for when perl will gain true
- native syntax support for try/catch control flow.
+ This module makes syntax support for try/catch control flow easily
+ available.
- Perl added such syntax in the development version 5.33.7, which is
- enabled by
+ Perl added such syntax at version 5.34.0, and extended it to support
+ optional finally blocks at 5.35.9, which is enabled by
use feature 'try';
@@ -49,7 +49,8 @@ KEYWORDS
...
A try statement provides the main body of code that will be invoked,
- and must be followed by a catch statement.
+ and must be followed by a catch statement. It may optionally be
+ followed by a finally statement.
Execution of the try statement itself begins from the block given to
the statement and continues until either it throws an exception, or
@@ -103,7 +104,28 @@ KEYWORDS
contain loop control expressions (redo, next or last) which also have
their usual effect.
-COMPATIBILITY NOTES
+ finally
+
+ ...
+ finally {
+ STATEMENTS...
+ }
+
+ A finally statement provides an optional block of code to the preceding
+ try/catch pair which is executed afterwards, both in the case of a
+ normal execution or a thrown exception. This code block may be used to
+ provide whatever clean-up operations might be required by preceding
+ code.
+
+ Because it is executed during a stack cleanup operation, a finally {}
+ block may not cause the containing function to return, or to alter the
+ return value of it. It also cannot see the containing function's @_
+ arguments array (though as it is block scoped within the function, it
+ will continue to share any normal lexical variables declared up until
+ that point). It is protected from disturbing the value of $@. If the
+ finally {} block code throws an exception, this will be printed as a
+ warning and discarded, leaving $@ containing the original exception, if
+ one existed. =head1 COMPATIBILITY NOTES
This module may use either Syntax::Keyword::Try or the perl core try
feature to implement its syntax. While the two behave very similarly,
@@ -126,6 +148,25 @@ COMPATIBILITY NOTES
frames in the way, you will need to somehow account for the
difference in stack height.
+ * B::Deparse
+
+ The core feature 'try' is implemented by emitting real opcodes that
+ represent its behaviour, which is recognised by the version of
+ B::Deparse that ships with core perl. As a result, any code using
+ this implementation will deparse currently with tools like perl
+ -MO=Deparse ..., or others related to it such as coverage checkers.
+
+ By comparison, since Syntax::Keyword::Try uses OP_CUSTOM it is not
+ recognised by B::Deparse and so attempts to deparse this will result
+ in error messages like
+
+ unexpected OP_CUSTOM (catch) at ...
+
+ This is rather unavoidable due to the way that B::Deparse is
+ implemented and does not easily support custom operators.
+
+ See also https://rt.cpan.org/Ticket/Display.html?id=134812.
+
AUTHOR
Paul Evans <leonerd@leonerd.org.uk>
diff --git a/lib/Feature/Compat/Try.pm b/lib/Feature/Compat/Try.pm
index 7630f91..c26b157 100644
--- a/lib/Feature/Compat/Try.pm
+++ b/lib/Feature/Compat/Try.pm
@@ -1,15 +1,16 @@
# You may distribute under the terms of either the GNU General Public License
# or the Artistic License (the same terms as Perl itself)
#
-# (C) Paul Evans, 2021 -- leonerd@leonerd.org.uk
+# (C) Paul Evans, 2021-2022 -- leonerd@leonerd.org.uk
-package Feature::Compat::Try 0.04;
+package Feature::Compat::Try 0.05;
use v5.14;
use warnings;
use feature ();
-use constant HAVE_FEATURE_TRY => defined $feature::feature{try};
+# Core's use feature 'try' only supports 'finally' since 5.35.8
+use constant HAVE_FEATURE_TRY => $] >= 5.035008;
=head1 NAME
@@ -33,11 +34,11 @@ C<Feature::Compat::Try> - make C<try/catch> syntax available
=head1 DESCRIPTION
-This module is written in preparation for when perl will gain true native
-syntax support for C<try/catch> control flow.
+This module makes syntax support for C<try/catch> control flow easily
+available.
-Perl added such syntax in the development version 5.33.7, which is enabled
-by
+Perl added such syntax at version 5.34.0, and extended it to support optional
+C<finally> blocks at 5.35.9, which is enabled by
use feature 'try';
@@ -63,7 +64,8 @@ still continue to function on that newer perl.
...
A C<try> statement provides the main body of code that will be invoked, and
-must be followed by a C<catch> statement.
+must be followed by a C<catch> statement. It may optionally be followed by
+a C<finally> statement.
Execution of the C<try> statement itself begins from the block given to the
statement and continues until either it throws an exception, or completes
@@ -114,6 +116,26 @@ containing function to return with the given value. The body may also contain
loop control expressions (C<redo>, C<next> or C<last>) which also have their
usual effect.
+=head2 finally
+
+ ...
+ finally {
+ STATEMENTS...
+ }
+
+A C<finally> statement provides an optional block of code to the preceding
+C<try>/C<catch> pair which is executed afterwards, both in the case of a
+normal execution or a thrown exception. This code block may be used to
+provide whatever clean-up operations might be required by preceding code.
+
+Because it is executed during a stack cleanup operation, a C<finally {}> block
+may not cause the containing function to return, or to alter the return value
+of it. It also cannot see the containing function's C<@_> arguments array
+(though as it is block scoped within the function, it will continue to share
+any normal lexical variables declared up until that point). It is protected
+from disturbing the value of C<$@>. If the C<finally {}> block code throws an
+exception, this will be printed as a warning and discarded, leaving C<$@>
+containing the original exception, if one existed.
=cut
sub import
@@ -125,8 +147,8 @@ sub import
}
else {
require Syntax::Keyword::Try;
- Syntax::Keyword::Try->VERSION( '0.22' );
- Syntax::Keyword::Try->import(qw( try -no_finally -require_var ));
+ Syntax::Keyword::Try->VERSION( '0.27' );
+ Syntax::Keyword::Try->import(qw( try -require_catch -require_var ));
}
}
@@ -154,6 +176,25 @@ fine here. But if you are using C<caller()> with calculated indexes to inspect
the state of callers to your code and there may be C<try> frames in the way,
you will need to somehow account for the difference in stack height.
+=item * C<B::Deparse>
+
+The core C<feature 'try'> is implemented by emitting real opcodes that
+represent its behaviour, which is recognised by the version of L<B::Deparse>
+that ships with core perl. As a result, any code using this implementation
+will deparse currently with tools like C<perl -MO=Deparse ...>, or others
+related to it such as coverage checkers.
+
+By comparison, since C<Syntax::Keyword::Try> uses C<OP_CUSTOM> it is not
+recognised by C<B::Deparse> and so attempts to deparse this will result in
+error messages like
+
+ unexpected OP_CUSTOM (catch) at ...
+
+This is rather unavoidable due to the way that C<B::Deparse> is implemented
+and does not easily support custom operators.
+
+See also L<https://rt.cpan.org/Ticket/Display.html?id=134812>.
+
=back
=cut
diff --git a/t/03trycatchfinally.t b/t/03trycatchfinally.t
new file mode 100644
index 0000000..882f13e
--- /dev/null
+++ b/t/03trycatchfinally.t
@@ -0,0 +1,42 @@
+#!/usr/bin/perl
+
+use v5.14;
+use warnings;
+
+use Test::More;
+
+use Feature::Compat::Try;
+
+# try success
+{
+ my $s;
+ try {
+ $s = 1; # overwritten
+ }
+ catch ($e) {
+ die "FAIL";
+ }
+ finally {
+ $s = 2;
+ }
+
+ is( $s, 2, 't/c/f runs finally' );
+}
+
+# try failure
+{
+ my $s;
+ try {
+ die "oopsie";
+ }
+ catch ($e) {
+ $s = 3;
+ }
+ finally {
+ $s++;
+ }
+
+ is( $s, 4, 't/c/f runs catch{} and finally{} on failure' );
+}
+
+done_testing;
diff --git a/t/12return.t b/t/12return.t
index 147c59d..89fad28 100644
--- a/t/12return.t
+++ b/t/12return.t
@@ -10,18 +10,25 @@ use Feature::Compat::Try;
# return from try
{
my $after;
+ ( sub {
+ try { return }
+ catch ($e) {}
+ $after++;
+ } )->();
+ ok( !$after, 'code after try{return} in void context is not invoked' );
+}
+# return SCALAR from try
+{
is(
- ( sub {
+ scalar ( sub {
try { return "result" }
catch ($e) {}
- $after++;
return "nope";
} )->(),
"result",
- 'return in try leaves containing function'
+ 'return SCALAR in try yields correct value'
);
- ok( !$after, 'code after try{return} is not invoked' );
}
# return LIST from try
diff --git a/t/16final-expr.t b/t/16final-expr.t
index ef3bb64..47388df 100644
--- a/t/16final-expr.t
+++ b/t/16final-expr.t
@@ -35,6 +35,12 @@ use Feature::Compat::Try;
catch ($e) { 4, 5, 6 }
};
is_deeply(\@list, [4, 5, 6], 'do { try/catch } in list context');
+
+ $scalar = do {
+ try { die "Oops" }
+ catch ($e) { my $x = 123; 456 }
+ };
+ is($scalar, 456, 'do { try/catch } with multiple statements');
}
done_testing;