diff --git a/Changes b/Changes index fbd6ecc..e7a99af 100644 --- a/Changes +++ b/Changes @@ -1,6 +1,8 @@ Revision history for {{$dist->name}} {{$NEXT}} + - Show the correct way to test eval success. (Dan Book) + - Add explanation for not relying on value of $@ (Dan Book) 0.102 2017-08-14 - Update the eval-ed code to be somewhat more readable diff --git a/META.json b/META.json index e2a0156..dc045d0 100644 --- a/META.json +++ b/META.json @@ -4,7 +4,7 @@ "Chase Whitener " ], "dynamic_config" : 0, - "generated_by" : "Dist::Zilla version 6.010, CPAN::Meta::Converter version 2.150010", + "generated_by" : "Dist::Zilla version 6.012, CPAN::Meta::Converter version 2.150010", "license" : [ "perl_5" ], @@ -71,15 +71,15 @@ "provides" : { "Exception" : { "file" : "lib/Exception.pm", - "version" : "0.102" + "version" : "0.103" }, "Exceptions" : { "file" : "lib/Exceptions.pm", - "version" : "0.102" + "version" : "0.103" }, "SimpleException" : { "file" : "lib/SimpleException.pm", - "version" : "0.102" + "version" : "0.103" } }, "release_status" : "stable", @@ -94,10 +94,10 @@ "web" : "https://github.com/genio/p5-exceptions" } }, - "version" : "0.102", + "version" : "0.103", "x_Dist_Zilla" : { "perl" : { - "version" : "5.026000" + "version" : "5.028000" }, "plugins" : [ { @@ -122,89 +122,32 @@ } }, "name" : "Git::GatherDir", - "version" : "2.042" - }, - { - "class" : "Dist::Zilla::Plugin::PruneCruft", - "name" : "@Starter/PruneCruft", - "version" : "6.010" - }, - { - "class" : "Dist::Zilla::Plugin::ManifestSkip", - "name" : "@Starter/ManifestSkip", - "version" : "6.010" - }, - { - "class" : "Dist::Zilla::Plugin::MetaConfig", - "name" : "@Starter/MetaConfig", - "version" : "6.010" - }, - { - "class" : "Dist::Zilla::Plugin::MetaProvides::Package", - "config" : { - "Dist::Zilla::Plugin::MetaProvides::Package" : { - "finder_objects" : [ - { - "class" : "Dist::Zilla::Plugin::FinderCode", - "name" : "@Starter/MetaProvides::Package/AUTOVIV/:InstallModulesPM", - "version" : "6.010" - } - ], - "include_underscores" : 0 - }, - "Dist::Zilla::Role::MetaProvider::Provider" : { - "$Dist::Zilla::Role::MetaProvider::Provider::VERSION" : "2.002004", - "inherit_missing" : 1, - "inherit_version" : 0, - "meta_noindex" : 1 - }, - "Dist::Zilla::Role::ModuleMetadata" : { - "Module::Metadata" : "1.000033", - "version" : "0.004" - } - }, - "name" : "@Starter/MetaProvides::Package", - "version" : "2.004003" - }, - { - "class" : "Dist::Zilla::Plugin::MetaNoIndex", - "name" : "@Starter/MetaNoIndex", - "version" : "6.010" + "version" : "2.045" }, { "class" : "Dist::Zilla::Plugin::MetaYAML", "name" : "@Starter/MetaYAML", - "version" : "6.010" + "version" : "6.012" }, { "class" : "Dist::Zilla::Plugin::MetaJSON", "name" : "@Starter/MetaJSON", - "version" : "6.010" + "version" : "6.012" }, { "class" : "Dist::Zilla::Plugin::License", "name" : "@Starter/License", - "version" : "6.010" + "version" : "6.012" }, { "class" : "Dist::Zilla::Plugin::Pod2Readme", "name" : "@Starter/Pod2Readme", "version" : "0.004" }, - { - "class" : "Dist::Zilla::Plugin::ExecDir", - "name" : "@Starter/ExecDir", - "version" : "6.010" - }, - { - "class" : "Dist::Zilla::Plugin::ShareDir", - "name" : "@Starter/ShareDir", - "version" : "6.010" - }, { "class" : "Dist::Zilla::Plugin::PodSyntaxTests", "name" : "@Starter/PodSyntaxTests", - "version" : "6.010" + "version" : "6.012" }, { "class" : "Dist::Zilla::Plugin::Test::ReportPrereqs", @@ -232,7 +175,7 @@ } }, "name" : "@Starter/Test::Compile", - "version" : "2.056" + "version" : "2.058" }, { "class" : "Dist::Zilla::Plugin::MakeMaker", @@ -242,17 +185,22 @@ } }, "name" : "@Starter/MakeMaker", - "version" : "6.010" + "version" : "6.012" }, { "class" : "Dist::Zilla::Plugin::Manifest", "name" : "@Starter/Manifest", - "version" : "6.010" + "version" : "6.012" }, { - "class" : "Dist::Zilla::Plugin::TestRelease", - "name" : "@Starter/TestRelease", - "version" : "6.010" + "class" : "Dist::Zilla::Plugin::PruneCruft", + "name" : "@Starter/PruneCruft", + "version" : "6.012" + }, + { + "class" : "Dist::Zilla::Plugin::ManifestSkip", + "name" : "@Starter/ManifestSkip", + "version" : "6.012" }, { "class" : "Dist::Zilla::Plugin::RunExtraTests", @@ -264,20 +212,83 @@ "name" : "@Starter/RunExtraTests", "version" : "0.029" }, + { + "class" : "Dist::Zilla::Plugin::TestRelease", + "name" : "@Starter/TestRelease", + "version" : "6.012" + }, { "class" : "Dist::Zilla::Plugin::ConfirmRelease", "name" : "@Starter/ConfirmRelease", - "version" : "6.010" + "version" : "6.012" }, { "class" : "Dist::Zilla::Plugin::UploadToCPAN", "name" : "@Starter/UploadToCPAN", - "version" : "6.010" + "version" : "6.012" + }, + { + "class" : "Dist::Zilla::Plugin::MetaConfig", + "name" : "@Starter/MetaConfig", + "version" : "6.012" }, { - "class" : "Dist::Zilla::Plugin::PkgVersion", - "name" : "PkgVersion", - "version" : "6.010" + "class" : "Dist::Zilla::Plugin::MetaNoIndex", + "name" : "@Starter/MetaNoIndex", + "version" : "6.012" + }, + { + "class" : "Dist::Zilla::Plugin::MetaProvides::Package", + "config" : { + "Dist::Zilla::Plugin::MetaProvides::Package" : { + "finder_objects" : [ + { + "class" : "Dist::Zilla::Plugin::FinderCode", + "name" : "@Starter/MetaProvides::Package/AUTOVIV/:InstallModulesPM", + "version" : "6.012" + } + ], + "include_underscores" : 0 + }, + "Dist::Zilla::Role::MetaProvider::Provider" : { + "$Dist::Zilla::Role::MetaProvider::Provider::VERSION" : "2.002004", + "inherit_missing" : 1, + "inherit_version" : 0, + "meta_noindex" : 1 + }, + "Dist::Zilla::Role::ModuleMetadata" : { + "Module::Metadata" : "1.000033", + "version" : "0.006" + } + }, + "name" : "@Starter/MetaProvides::Package", + "version" : "2.004003" + }, + { + "class" : "Dist::Zilla::Plugin::ShareDir", + "name" : "@Starter/ShareDir", + "version" : "6.012" + }, + { + "class" : "Dist::Zilla::Plugin::ExecDir", + "name" : "@Starter/ExecDir", + "version" : "6.012" + }, + { + "class" : "Dist::Zilla::Plugin::RewriteVersion", + "config" : { + "Dist::Zilla::Plugin::RewriteVersion" : { + "add_tarball_name" : 0, + "finders" : [ + ":ExecFiles", + ":InstallModules" + ], + "global" : 1, + "skip_version_provider" : 1 + } + }, + "name" : "RewriteVersion", + "version" : "0.018" }, { "class" : "Dist::Zilla::Plugin::ReadmeAnyFromPod", @@ -302,7 +313,7 @@ { "class" : "Dist::Zilla::Plugin::FinderCode", "name" : "MetaProvides::Package/AUTOVIV/:InstallModulesPM", - "version" : "6.010" + "version" : "6.012" } ], "include_underscores" : 0 @@ -315,7 +326,7 @@ }, "Dist::Zilla::Role::ModuleMetadata" : { "Module::Metadata" : "1.000033", - "version" : "0.004" + "version" : "0.006" } }, "name" : "MetaProvides::Package", @@ -324,13 +335,28 @@ { "class" : "Dist::Zilla::Plugin::NextRelease", "name" : "NextRelease", - "version" : "6.010" + "version" : "6.012" + }, + { + "class" : "Dist::Zilla::Plugin::BumpVersionAfterRelease", + "config" : { + "Dist::Zilla::Plugin::BumpVersionAfterRelease" : { + "finders" : [ + ":ExecFiles", + ":InstallModules" + ], + "global" : 0, + "munge_makefile_pl" : 1 + } + }, + "name" : "BumpVersionAfterRelease", + "version" : "0.018" }, { "class" : "Dist::Zilla::Plugin::Git::Contributors", "config" : { "Dist::Zilla::Plugin::Git::Contributors" : { - "git_version" : "2.11.0 (Apple Git-81)", + "git_version" : "2.17.1", "include_authors" : 0, "include_releaser" : 1, "order_by" : "name", @@ -338,12 +364,12 @@ } }, "name" : "Git::Contributors", - "version" : "0.030" + "version" : "0.035" }, { "class" : "Dist::Zilla::Plugin::GithubMeta", "name" : "GithubMeta", - "version" : "0.54" + "version" : "0.58" }, { "class" : "Dist::Zilla::Plugin::Git::Check", @@ -360,12 +386,12 @@ "changelog" : "Changes" }, "Dist::Zilla::Role::Git::Repo" : { - "git_version" : "2.11.0 (Apple Git-81)", + "git_version" : "2.17.1", "repo_root" : "." } }, "name" : "@Git/Check", - "version" : "2.042" + "version" : "2.045" }, { "class" : "Dist::Zilla::Plugin::Git::Commit", @@ -383,7 +409,7 @@ "changelog" : "Changes" }, "Dist::Zilla::Role::Git::Repo" : { - "git_version" : "2.11.0 (Apple Git-81)", + "git_version" : "2.17.1", "repo_root" : "." }, "Dist::Zilla::Role::Git::StringFormatter" : { @@ -391,7 +417,7 @@ } }, "name" : "@Git/Commit", - "version" : "2.042" + "version" : "2.045" }, { "class" : "Dist::Zilla::Plugin::Git::Tag", @@ -400,12 +426,12 @@ "branch" : null, "changelog" : "Changes", "signed" : 0, - "tag" : "v0.102", + "tag" : "v0.103", "tag_format" : "v%v", "tag_message" : "v%v" }, "Dist::Zilla::Role::Git::Repo" : { - "git_version" : "2.11.0 (Apple Git-81)", + "git_version" : "2.17.1", "repo_root" : "." }, "Dist::Zilla::Role::Git::StringFormatter" : { @@ -413,7 +439,7 @@ } }, "name" : "@Git/Tag", - "version" : "2.042" + "version" : "2.045" }, { "class" : "Dist::Zilla::Plugin::Git::Push", @@ -425,12 +451,12 @@ "remotes_must_exist" : 1 }, "Dist::Zilla::Role::Git::Repo" : { - "git_version" : "2.11.0 (Apple Git-81)", + "git_version" : "2.17.1", "repo_root" : "." } }, "name" : "@Git/Push", - "version" : "2.042" + "version" : "2.045" }, { "class" : "Dist::Zilla::Plugin::Test::Portability", @@ -487,22 +513,22 @@ { "class" : "Dist::Zilla::Plugin::MetaTests", "name" : "MetaTests", - "version" : "6.010" + "version" : "6.012" }, { "class" : "Dist::Zilla::Plugin::CheckChangeLog", "name" : "CheckChangeLog", - "version" : "0.04" + "version" : "0.05" }, { "class" : "Dist::Zilla::Plugin::CheckChangesHasContent", "name" : "CheckChangesHasContent", - "version" : "0.010" + "version" : "0.011" }, { "class" : "Dist::Zilla::Plugin::Test::ChangesHasContent", "name" : "Test::ChangesHasContent", - "version" : "0.010" + "version" : "0.011" }, { "class" : "Dist::Zilla::Plugin::Test::Kwalitee", @@ -523,7 +549,7 @@ { "class" : "Dist::Zilla::Plugin::Test::Pod::Coverage::Configurable", "name" : "Test::Pod::Coverage::Configurable", - "version" : "0.06" + "version" : "0.07" }, { "class" : "Dist::Zilla::Plugin::Test::PodSpelling", @@ -541,7 +567,7 @@ } }, "name" : "Test::PodSpelling", - "version" : "2.007004" + "version" : "2.007005" }, { "class" : "Dist::Zilla::Plugin::CopyFilesFromBuild", @@ -551,62 +577,62 @@ { "class" : "Dist::Zilla::Plugin::FinderCode", "name" : ":InstallModules", - "version" : "6.010" + "version" : "6.012" }, { "class" : "Dist::Zilla::Plugin::FinderCode", "name" : ":IncModules", - "version" : "6.010" + "version" : "6.012" }, { "class" : "Dist::Zilla::Plugin::FinderCode", "name" : ":TestFiles", - "version" : "6.010" + "version" : "6.012" }, { "class" : "Dist::Zilla::Plugin::FinderCode", "name" : ":ExtraTestFiles", - "version" : "6.010" + "version" : "6.012" }, { "class" : "Dist::Zilla::Plugin::FinderCode", "name" : ":ExecFiles", - "version" : "6.010" + "version" : "6.012" }, { "class" : "Dist::Zilla::Plugin::FinderCode", "name" : ":PerlExecFiles", - "version" : "6.010" + "version" : "6.012" }, { "class" : "Dist::Zilla::Plugin::FinderCode", "name" : ":ShareFiles", - "version" : "6.010" + "version" : "6.012" }, { "class" : "Dist::Zilla::Plugin::FinderCode", "name" : ":MainModule", - "version" : "6.010" + "version" : "6.012" }, { "class" : "Dist::Zilla::Plugin::FinderCode", "name" : ":AllFiles", - "version" : "6.010" + "version" : "6.012" }, { "class" : "Dist::Zilla::Plugin::FinderCode", "name" : ":NoFiles", - "version" : "6.010" + "version" : "6.012" }, { "class" : "Dist::Zilla::Plugin::FinderCode", "name" : "@Starter/MetaProvides::Package/AUTOVIV/:InstallModulesPM", - "version" : "6.010" + "version" : "6.012" }, { "class" : "Dist::Zilla::Plugin::FinderCode", "name" : "MetaProvides::Package/AUTOVIV/:InstallModulesPM", - "version" : "6.010" + "version" : "6.012" } ], "zilla" : { @@ -614,9 +640,13 @@ "config" : { "is_trial" : 0 }, - "version" : "6.010" + "version" : "6.012" } }, - "x_serialization_backend" : "Cpanel::JSON::XS version 3.0233" + "x_contributors" : [ + "Dan Book " + ], + "x_generated_by_perl" : "v5.28.0", + "x_serialization_backend" : "Cpanel::JSON::XS version 4.06" } diff --git a/Makefile.PL b/Makefile.PL index 84b5ff6..99cd3d1 100644 --- a/Makefile.PL +++ b/Makefile.PL @@ -1,4 +1,4 @@ -# This file was automatically generated by Dist::Zilla::Plugin::MakeMaker v6.010. +# This file was automatically generated by Dist::Zilla::Plugin::MakeMaker v6.012. use strict; use warnings; @@ -24,7 +24,7 @@ my %WriteMakefileArgs = ( "File::Spec" => 0, "Test::More" => "0.88" }, - "VERSION" => "0.102", + "VERSION" => "0.103", "test" => { "TESTS" => "t/*.t" } diff --git a/README.md b/README.md index e396cde..2225336 100644 --- a/README.md +++ b/README.md @@ -42,25 +42,29 @@ the _why_ of it all. An exception is what happens anytime your program's execution exits unexpectedly. Let's start with a simple example. - #!/usr/bin/env perl - use strict; - use warnings; - - print "0 plus 1 = ", increment(0), "\n"; # 1 - print "zero plus 1 = ", increment('zero'), "\n"; # Exception - print "0 plus 1 = ", increment(0), "\n"; # never executes - - sub increment { - my $int = shift; - die "That's not an int!" unless defined $int && $int =~ /^[0-9]+\z/; - return $int+1; - } +```perl +#!/usr/bin/env perl +use strict; +use warnings; + +print "0 plus 1 = ", increment(0), "\n"; # 1 +print "zero plus 1 = ", increment('zero'), "\n"; # Exception +print "0 plus 1 = ", increment(0), "\n"; # never executes + +sub increment { + my $int = shift; + die "That's not an int!" unless defined $int && $int =~ /^[0-9]+\z/; + return $int+1; +} +``` This will result in the following output: - $ perl increment.pl - 0 plus 1 = 1 - That's not an int! at foo.pl line 11. +``` +$ perl increment.pl +0 plus 1 = 1 +That's not an int! at foo.pl line 11. +``` The first line prints `0 plus 1 = 1\n` as expected. The second line, however, dies in a way that we can't recover from which prevents the rest of our program @@ -73,49 +77,50 @@ die in an `eval` block. This sounds simple enough, but there are some gotchas that lead many developers to do this incorrectly. The correct way to handle an exception requires that you understand how to -preserve the global `$@` variable. Please see ["BACKGROUND" in Try::Tiny](https://metacpan.org/pod/Try::Tiny#BACKGROUND) for a +preserve the global `$@` variable and that its value cannot be relied upon to +determine whether an exception occurred. Please see ["BACKGROUND" in Try::Tiny](https://metacpan.org/pod/Try::Tiny#BACKGROUND) for a great explanation of this problem. Let's look at our previous simple application with error handling using `eval`. - #!/usr/bin/env perl - use strict; - use warnings; - - # 1 - my $value; - my $error = do { # catch block - local $@; - eval { $value = increment(0) }; # try - $@; - }; - print "0 plus 1 = ", ($error ? "error": $value), "\n"; - - # error - $value = undef; - $error = undef; - $error = do { # catch block - local $@; - eval { $value = increment('zero') }; # try - $@; - }; - print "zero plus 1 = ", ($error ? "error": $value), "\n"; - - # 1 - $value = undef; - $error = undef; - $error = do { # catch block - local $@; - eval { $value = increment(0) }; # try - $@; - }; - print "0 plus 1 = ", ($error ? "error": $value), "\n"; - - sub increment { - my $int = shift; - die "That's not an int!" unless defined $int && $int =~ /^[0-9]+\z/; - return $int+1; - } +```perl +#!/usr/bin/env perl +use strict; +use warnings; + +# 1 +my $value; +my $error; +{ # catch block + local $@; + $error = $@ || 'Error' unless eval { $value = increment(0); 1 }; # try +} +print "0 plus 1 = ", (defined $error ? "error": $value), "\n"; + +# error +$value = undef; +$error = undef; +{ # catch block + local $@; + $error = $@ || 'Error' unless eval { $value = increment('zero'); 1 }; # try +} +print "zero plus 1 = ", (defined $error ? "error": $value), "\n"; + +# 1 +$value = undef; +$error = undef; +{ # catch block + local $@; + $error = $@ || 'Error' unless eval { $value = increment(0); 1 }; # try +} +print "0 plus 1 = ", (defined $error ? "error": $value), "\n"; + +sub increment { + my $int = shift; + die "That's not an int!" unless defined $int && $int =~ /^[0-9]+\z/; + return $int+1; +} +``` As you can see, it gets quite ugly and cumbersome to handle exceptions this way. Don't let that scare you away from Perl, though. Keep reading and be happy! @@ -128,56 +133,60 @@ solutions to common tasks for us. One such solution is [Syntax::Keyword::Try](ht If you get nothing else out of this document, let it be that using [Syntax::Keyword::Try](https://metacpan.org/pod/Syntax::Keyword::Try) will save you time and heartache. - #!/usr/bin/env perl - use strict; - use warnings; - use Syntax::Keyword::Try; - # since 5.14 is required, let's use those features - use feature ':5.14'; - - # 1 - try { say "0 plus 1 = ", increment(0); } - catch { say "0 plus 1 = error"; } - - # error - try { say "zero plus 1 = ", increment('zero'); } - catch { say "zero plus 1 = error"; } - - # 1 - try { say "0 plus 1 = ", increment(0); } - catch { say "0 plus 1 = error"; } - - sub increment { - my $int = shift; - die "That's not an int!" unless defined $int && $int =~ /^[0-9]+\z/; - return $int+1; - } +```perl +#!/usr/bin/env perl +use strict; +use warnings; +use Syntax::Keyword::Try; +# since 5.14 is required, let's use those features +use feature ':5.14'; + +# 1 +try { say "0 plus 1 = ", increment(0); } +catch { say "0 plus 1 = error"; } + +# error +try { say "zero plus 1 = ", increment('zero'); } +catch { say "zero plus 1 = error"; } + +# 1 +try { say "0 plus 1 = ", increment(0); } +catch { say "0 plus 1 = error"; } + +sub increment { + my $int = shift; + die "That's not an int!" unless defined $int && $int =~ /^[0-9]+\z/; + return $int+1; +} +``` If you can't use [Syntax::Keyword::Try](https://metacpan.org/pod/Syntax::Keyword::Try), you can use the pure-Perl [Try::Tiny](https://metacpan.org/pod/Try::Tiny) instead: - #!/usr/bin/env perl - use strict; - use warnings; - use Try::Tiny qw(try catch); - - # 1 - try { print "0 plus 1 = ", increment(0), "\n"; } - catch { print "0 plus 1 = error\n"; }; - - # error - try { print "zero plus 1 = ", increment('zero'), "\n"; } - catch { print "zero plus 1 = error\n"; }; - - # 1 - try { print "0 plus 1 = ", increment(0), "\n"; } - catch { print "0 plus 1 = error\n"; }; - - sub increment { - my $int = shift; - die "That's not an int!" unless defined $int && $int =~ /^[0-9]+\z/; - return $int+1; - } +```perl +#!/usr/bin/env perl +use strict; +use warnings; +use Try::Tiny qw(try catch); + +# 1 +try { print "0 plus 1 = ", increment(0), "\n"; } +catch { print "0 plus 1 = error\n"; }; + +# error +try { print "zero plus 1 = ", increment('zero'), "\n"; } +catch { print "zero plus 1 = error\n"; }; + +# 1 +try { print "0 plus 1 = ", increment(0), "\n"; } +catch { print "0 plus 1 = error\n"; }; + +sub increment { + my $int = shift; + die "That's not an int!" unless defined $int && $int =~ /^[0-9]+\z/; + return $int+1; +} +``` # AUTHOR diff --git a/dist.ini b/dist.ini index 99b5c5c..a611055 100644 --- a/dist.ini +++ b/dist.ini @@ -4,7 +4,7 @@ license = Perl_5 copyright_holder = Chase Whitener copyright_year = 2016 -version = 0.102 +version = 0.103 [Git::GatherDir] exclude_filename = Makefile.PL @@ -15,12 +15,14 @@ exclude_filename = LICENSE [@Starter] -remove = GatherDir revision = 2 -ReadmeAnyFromPod.source_filename = lib/Exceptions.pm -[PkgVersion] +[RewriteVersion] +global = 1 +skip_version_provider = 1 [ReadmeAnyFromPod / Markdown_Readme] -type = markdown +type = gfm +source_filename = lib/Exceptions.pm filename = README.md location = root @@ -30,6 +32,8 @@ location = root [NextRelease] format = %-9v %{yyyy-MM-dd}d +[BumpVersionAfterRelease] + [Git::Contributors] [GithubMeta] issues = 1 @@ -55,6 +59,9 @@ spell_cmd = aspell list stopword = Seibel [CopyFilesFromBuild] +copy = lib/Exception.pm +copy = lib/Exceptions.pm +copy = lib/SimpleException.pm copy = Makefile.PL copy = META.json copy = LICENSE diff --git a/lib/Exception.pm b/lib/Exception.pm index e44a6ba..b49d884 100644 --- a/lib/Exception.pm +++ b/lib/Exception.pm @@ -1,5 +1,7 @@ package Exception; +our $VERSION = '0.103'; + use strict; use warnings; diff --git a/lib/Exceptions.pm b/lib/Exceptions.pm index 039315c..f72f26d 100644 --- a/lib/Exceptions.pm +++ b/lib/Exceptions.pm @@ -1,5 +1,7 @@ package Exceptions; +our $VERSION = '0.103'; + use strict; use warnings; diff --git a/lib/SimpleException.pm b/lib/SimpleException.pm index f235c76..a5e053f 100644 --- a/lib/SimpleException.pm +++ b/lib/SimpleException.pm @@ -1,5 +1,7 @@ package SimpleException; +our $VERSION = '0.103'; + use strict; use warnings;