diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..966d7e9 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,22 @@ +# Set default behaviour, in case users don't have core.autocrlf set. +* text=lf + +# Explicitly declare text files we want to always be normalized and converted +# to native line endings on checkout. +*.c text eol=lf +*.h text eol=lf +*.pl text eol=lf +*.pm text eol=lf +*.php text eol=lf +*.t text eol=lf +*.html text eol=lf + +# Declare files that will always have CRLF line endings on checkout. +*.sln text eol=crlf + +# Denote all files that are truly binary and should not be modified. +*.png binary +*.jpg binary + +.gitattributes export-ignore +.gitignore export-ignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..db01d7a --- /dev/null +++ b/.gitignore @@ -0,0 +1,10 @@ +Exceptions-*.tar.gz +Exceptions-*/ +Build +META.yml +MYMETA.json +MYMETA.yml +_build/ +blib/ +cover_db/ +.build/ diff --git a/.mailmap b/.mailmap new file mode 100644 index 0000000..1227d4e --- /dev/null +++ b/.mailmap @@ -0,0 +1,2 @@ +Chase Whitener +Chase Whitener diff --git a/.perltidyrc b/.perltidyrc new file mode 100644 index 0000000..2792697 --- /dev/null +++ b/.perltidyrc @@ -0,0 +1,12 @@ +-pbp # Start with Perl Best Practices +-w # Show all warnings +-iob # Ignore old breakpoints +-l=80 # 80 characters per line +-mbl=2 # No more than 2 blank lines +-i=4 # Indentation is 2 columns +-ci=4 # Continuation indentation is 2 columns +-vt=0 # Less vertical tightness +-pt=2 # High parenthesis tightness +-bt=2 # High brace tightness +-sbt=2 # High square bracket tightness +-isbc # Don't indent comments without leading space diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..2286b00 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,21 @@ +language: perl +perl: + - "5.22" + - "5.20" + - "5.18" + - "5.16" + - "5.14" + - "5.12" + - "5.10" + - "5.8" +env: + - "AUTOMATED_TESTING=1 AUTHOR_TESTING=1 RELEASE_TESTING=1" +install: + - "cpanm -n Test::More Test::Pod Test::Pod::Coverage Test::CheckManifest" + - "cpanm -n Test::CPAN::Changes Test::Kwalitee Test::Pod::Spelling::CommonMistakes" + - "cpanm -n --installdeps ." +script: + - perl Makefile.PL && make manifest && make test +sudo: false +notifications: + email: false diff --git a/Changes b/Changes new file mode 100644 index 0000000..da8cc7d --- /dev/null +++ b/Changes @@ -0,0 +1,7 @@ +Revision history for {{$dist->name}} + +{{$NEXT}} + - Dist::Zilla now used + +0.01 Wed Nov 27 13:48:49 1996 + - original version; created by h2xs 1.1.1.10 diff --git a/META.json b/META.json new file mode 100644 index 0000000..5c8e4ad --- /dev/null +++ b/META.json @@ -0,0 +1,544 @@ +{ + "abstract" : "Documentation for exception handling in Perl.", + "author" : [ + "Chase Whitener " + ], + "dynamic_config" : 0, + "generated_by" : "Dist::Zilla version 6.007, CPAN::Meta::Converter version 2.150005", + "license" : [ + "perl_5" + ], + "meta-spec" : { + "url" : "http://search.cpan.org/perldoc?CPAN::Meta::Spec", + "version" : 2 + }, + "name" : "Exceptions", + "no_index" : { + "directory" : [ + "eg", + "examples", + "inc", + "share", + "t", + "xt" + ] + }, + "prereqs" : { + "configure" : { + "requires" : { + "ExtUtils::MakeMaker" : "0" + } + }, + "develop" : { + "requires" : { + "File::Spec" : "0", + "IO::Handle" : "0", + "IPC::Open3" : "0", + "Pod::Coverage::TrustPod" : "0", + "Test::CPAN::Changes" : "0.4", + "Test::CheckManifest" : "1.29", + "Test::Kwalitee" : "1.22", + "Test::More" : "0.88", + "Test::Pod" : "1.41", + "Test::Pod::Coverage" : "1.08", + "Test::Pod::Spelling::CommonMistakes" : "1.000", + "Test::Spelling" : "0.12", + "Test::Version" : "1" + } + }, + "runtime" : { + "requires" : { + "strict" : "0", + "warnings" : "0" + } + }, + "test" : { + "recommends" : { + "CPAN::Meta" : "2.120900" + }, + "requires" : { + "ExtUtils::MakeMaker" : "0", + "File::Spec" : "0", + "Test::More" : "0.88" + } + } + }, + "provides" : { + "Exception" : { + "file" : "lib/Exception.pm", + "version" : "0.100" + }, + "Exceptions" : { + "file" : "lib/Exceptions.pm", + "version" : "0.100" + }, + "SimpleException" : { + "file" : "lib/SimpleException.pm", + "version" : "0.100" + } + }, + "release_status" : "stable", + "version" : "0.100", + "x_Dist_Zilla" : { + "perl" : { + "version" : "5.024000" + }, + "plugins" : [ + { + "class" : "Dist::Zilla::Plugin::GatherDir", + "config" : { + "Dist::Zilla::Plugin::GatherDir" : { + "exclude_filename" : [ + "META.json", + "Makefile.PL", + "README.md" + ], + "exclude_match" : [], + "follow_symlinks" : 0, + "include_dotfiles" : 0, + "prefix" : "", + "prune_directory" : [], + "root" : "." + } + }, + "name" : "@Starter/GatherDir", + "version" : "6.007" + }, + { + "class" : "Dist::Zilla::Plugin::PruneCruft", + "name" : "@Starter/PruneCruft", + "version" : "6.007" + }, + { + "class" : "Dist::Zilla::Plugin::ManifestSkip", + "name" : "@Starter/ManifestSkip", + "version" : "6.007" + }, + { + "class" : "Dist::Zilla::Plugin::MetaConfig", + "name" : "@Starter/MetaConfig", + "version" : "6.007" + }, + { + "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.007" + } + ], + "include_underscores" : 0 + }, + "Dist::Zilla::Role::MetaProvider::Provider" : { + "$Dist::Zilla::Role::MetaProvider::Provider::VERSION" : "2.002003", + "inherit_missing" : "1", + "inherit_version" : "1", + "meta_noindex" : "1" + }, + "Dist::Zilla::Role::ModuleMetadata" : { + "Module::Metadata" : "1.000031", + "version" : "0.004" + } + }, + "name" : "@Starter/MetaProvides::Package", + "version" : "2.004002" + }, + { + "class" : "Dist::Zilla::Plugin::MetaNoIndex", + "name" : "@Starter/MetaNoIndex", + "version" : "6.007" + }, + { + "class" : "Dist::Zilla::Plugin::MetaYAML", + "name" : "@Starter/MetaYAML", + "version" : "6.007" + }, + { + "class" : "Dist::Zilla::Plugin::MetaJSON", + "name" : "@Starter/MetaJSON", + "version" : "6.007" + }, + { + "class" : "Dist::Zilla::Plugin::License", + "name" : "@Starter/License", + "version" : "6.007" + }, + { + "class" : "Dist::Zilla::Plugin::ReadmeAnyFromPod", + "config" : { + "Dist::Zilla::Role::FileWatcher" : { + "version" : "0.006" + } + }, + "name" : "@Starter/ReadmeAnyFromPod", + "version" : "0.161170" + }, + { + "class" : "Dist::Zilla::Plugin::ExecDir", + "name" : "@Starter/ExecDir", + "version" : "6.007" + }, + { + "class" : "Dist::Zilla::Plugin::ShareDir", + "name" : "@Starter/ShareDir", + "version" : "6.007" + }, + { + "class" : "Dist::Zilla::Plugin::PodSyntaxTests", + "name" : "@Starter/PodSyntaxTests", + "version" : "6.007" + }, + { + "class" : "Dist::Zilla::Plugin::Test::ReportPrereqs", + "name" : "@Starter/Test::ReportPrereqs", + "version" : "0.025" + }, + { + "class" : "Dist::Zilla::Plugin::Test::Compile", + "config" : { + "Dist::Zilla::Plugin::Test::Compile" : { + "bail_out_on_fail" : "0", + "fail_on_warning" : "author", + "fake_home" : 0, + "filename" : "xt/author/00-compile.t", + "module_finder" : [ + ":InstallModules" + ], + "needs_display" : 0, + "phase" : "develop", + "script_finder" : [ + ":PerlExecFiles" + ], + "skips" : [] + } + }, + "name" : "@Starter/Test::Compile", + "version" : "2.054" + }, + { + "class" : "Dist::Zilla::Plugin::MakeMaker", + "config" : { + "Dist::Zilla::Role::TestRunner" : { + "default_jobs" : 1 + } + }, + "name" : "@Starter/MakeMaker", + "version" : "6.007" + }, + { + "class" : "Dist::Zilla::Plugin::Manifest", + "name" : "@Starter/Manifest", + "version" : "6.007" + }, + { + "class" : "Dist::Zilla::Plugin::TestRelease", + "name" : "@Starter/TestRelease", + "version" : "6.007" + }, + { + "class" : "Dist::Zilla::Plugin::RunExtraTests", + "config" : { + "Dist::Zilla::Role::TestRunner" : { + "default_jobs" : 1 + } + }, + "name" : "@Starter/RunExtraTests", + "version" : "0.029" + }, + { + "class" : "Dist::Zilla::Plugin::ConfirmRelease", + "name" : "@Starter/ConfirmRelease", + "version" : "6.007" + }, + { + "class" : "Dist::Zilla::Plugin::UploadToCPAN", + "name" : "@Starter/UploadToCPAN", + "version" : "6.007" + }, + { + "class" : "Dist::Zilla::Plugin::ReadmeAnyFromPod", + "config" : { + "Dist::Zilla::Role::FileWatcher" : { + "version" : "0.006" + } + }, + "name" : "Markdown_Readme", + "version" : "0.161170" + }, + { + "class" : "Dist::Zilla::Plugin::Prereqs::FromCPANfile", + "name" : "Prereqs::FromCPANfile", + "version" : "0.08" + }, + { + "class" : "Dist::Zilla::Plugin::MetaProvides::Package", + "config" : { + "Dist::Zilla::Plugin::MetaProvides::Package" : { + "finder_objects" : [ + { + "class" : "Dist::Zilla::Plugin::FinderCode", + "name" : "MetaProvides::Package/AUTOVIV/:InstallModulesPM", + "version" : "6.007" + } + ], + "include_underscores" : 0 + }, + "Dist::Zilla::Role::MetaProvider::Provider" : { + "$Dist::Zilla::Role::MetaProvider::Provider::VERSION" : "2.002003", + "inherit_missing" : "1", + "inherit_version" : "1", + "meta_noindex" : "1" + }, + "Dist::Zilla::Role::ModuleMetadata" : { + "Module::Metadata" : "1.000031", + "version" : "0.004" + } + }, + "name" : "MetaProvides::Package", + "version" : "2.004002" + }, + { + "class" : "Dist::Zilla::Plugin::NextRelease", + "name" : "NextRelease", + "version" : "6.007" + }, + { + "class" : "Dist::Zilla::Plugin::Git::Contributors", + "config" : { + "Dist::Zilla::Plugin::Git::Contributors" : { + "git --version" : "2.7.4 (Apple Git-66)", + "include_authors" : 0, + "include_releaser" : 1, + "order_by" : "name", + "paths" : [ + "." + ] + } + }, + "name" : "Git::Contributors", + "version" : "0.024" + }, + { + "class" : "Dist::Zilla::Plugin::GithubMeta", + "name" : "GithubMeta", + "version" : "0.54" + }, + { + "class" : "Dist::Zilla::Plugin::Git::Check", + "config" : { + "Dist::Zilla::Plugin::Git::Check" : { + "untracked_files" : "die" + }, + "Dist::Zilla::Role::Git::DirtyFiles" : { + "allow_dirty" : [ + "Changes", + "dist.ini" + ], + "allow_dirty_match" : [], + "changelog" : "Changes" + }, + "Dist::Zilla::Role::Git::Repo" : { + "repo_root" : "." + } + }, + "name" : "@Git/Check", + "version" : "2.039" + }, + { + "class" : "Dist::Zilla::Plugin::Git::Commit", + "config" : { + "Dist::Zilla::Plugin::Git::Commit" : { + "add_files_in" : [], + "commit_msg" : "v%v%n%n%c" + }, + "Dist::Zilla::Role::Git::DirtyFiles" : { + "allow_dirty" : [ + "Changes", + "dist.ini" + ], + "allow_dirty_match" : [], + "changelog" : "Changes" + }, + "Dist::Zilla::Role::Git::Repo" : { + "repo_root" : "." + }, + "Dist::Zilla::Role::Git::StringFormatter" : { + "time_zone" : "local" + } + }, + "name" : "@Git/Commit", + "version" : "2.039" + }, + { + "class" : "Dist::Zilla::Plugin::Git::Tag", + "config" : { + "Dist::Zilla::Plugin::Git::Tag" : { + "branch" : null, + "changelog" : "Changes", + "signed" : 0, + "tag" : "v0.100", + "tag_format" : "v%v", + "tag_message" : "v%v" + }, + "Dist::Zilla::Role::Git::Repo" : { + "repo_root" : "." + }, + "Dist::Zilla::Role::Git::StringFormatter" : { + "time_zone" : "local" + } + }, + "name" : "@Git/Tag", + "version" : "2.039" + }, + { + "class" : "Dist::Zilla::Plugin::Git::Push", + "config" : { + "Dist::Zilla::Plugin::Git::Push" : { + "push_to" : [ + "origin" + ], + "remotes_must_exist" : 1 + }, + "Dist::Zilla::Role::Git::Repo" : { + "repo_root" : "." + } + }, + "name" : "@Git/Push", + "version" : "2.039" + }, + { + "class" : "Dist::Zilla::Plugin::CheckChangeLog", + "name" : "CheckChangeLog", + "version" : "0.02" + }, + { + "class" : "Dist::Zilla::Plugin::CheckChangesHasContent", + "name" : "CheckChangesHasContent", + "version" : "0.010" + }, + { + "class" : "Dist::Zilla::Plugin::Test::ChangesHasContent", + "name" : "Test::ChangesHasContent", + "version" : "0.010" + }, + { + "class" : "Dist::Zilla::Plugin::PkgVersion", + "name" : "PkgVersion", + "version" : "6.007" + }, + { + "class" : "Dist::Zilla::Plugin::Test::Kwalitee", + "config" : { + "Dist::Zilla::Plugin::Test::Kwalitee" : { + "filename" : "xt/release/kwalitee.t", + "skiptest" : [] + } + }, + "name" : "Test::Kwalitee", + "version" : "2.12" + }, + { + "class" : "Dist::Zilla::Plugin::Test::Version", + "name" : "Test::Version", + "version" : "1.09" + }, + { + "class" : "Dist::Zilla::Plugin::Test::Pod::Coverage::Configurable", + "name" : "Test::Pod::Coverage::Configurable", + "version" : "0.06" + }, + { + "class" : "Dist::Zilla::Plugin::Test::PodSpelling", + "config" : { + "Dist::Zilla::Plugin::Test::PodSpelling" : { + "directories" : [], + "spell_cmd" : "aspell list", + "stopwords" : [ + "Seibel" + ], + "wordlist" : "Pod::Wordlist" + } + }, + "name" : "Test::PodSpelling", + "version" : "2.007002" + }, + { + "class" : "Dist::Zilla::Plugin::CopyFilesFromBuild", + "name" : "CopyFilesFromBuild", + "version" : "0.161350" + }, + { + "class" : "Dist::Zilla::Plugin::FinderCode", + "name" : ":InstallModules", + "version" : "6.007" + }, + { + "class" : "Dist::Zilla::Plugin::FinderCode", + "name" : ":IncModules", + "version" : "6.007" + }, + { + "class" : "Dist::Zilla::Plugin::FinderCode", + "name" : ":TestFiles", + "version" : "6.007" + }, + { + "class" : "Dist::Zilla::Plugin::FinderCode", + "name" : ":ExtraTestFiles", + "version" : "6.007" + }, + { + "class" : "Dist::Zilla::Plugin::FinderCode", + "name" : ":ExecFiles", + "version" : "6.007" + }, + { + "class" : "Dist::Zilla::Plugin::FinderCode", + "name" : ":PerlExecFiles", + "version" : "6.007" + }, + { + "class" : "Dist::Zilla::Plugin::FinderCode", + "name" : ":ShareFiles", + "version" : "6.007" + }, + { + "class" : "Dist::Zilla::Plugin::FinderCode", + "name" : ":MainModule", + "version" : "6.007" + }, + { + "class" : "Dist::Zilla::Plugin::FinderCode", + "name" : ":AllFiles", + "version" : "6.007" + }, + { + "class" : "Dist::Zilla::Plugin::FinderCode", + "name" : ":NoFiles", + "version" : "6.007" + }, + { + "class" : "Dist::Zilla::Plugin::FinderCode", + "name" : "@Starter/MetaProvides::Package/AUTOVIV/:InstallModulesPM", + "version" : "6.007" + }, + { + "class" : "Dist::Zilla::Plugin::FinderCode", + "name" : "MetaProvides::Package/AUTOVIV/:InstallModulesPM", + "version" : "6.007" + } + ], + "zilla" : { + "class" : "Dist::Zilla::Dist::Builder", + "config" : { + "is_trial" : "0" + }, + "version" : "6.007" + } + }, + "x_serialization_backend" : "Cpanel::JSON::XS version 3.0217" +} + diff --git a/Makefile.PL b/Makefile.PL new file mode 100644 index 0000000..d5e0533 --- /dev/null +++ b/Makefile.PL @@ -0,0 +1,52 @@ +# This file was automatically generated by Dist::Zilla::Plugin::MakeMaker v6.007. +use strict; +use warnings; + + + +use ExtUtils::MakeMaker; + +my %WriteMakefileArgs = ( + "ABSTRACT" => "Documentation for exception handling in Perl.", + "AUTHOR" => "Chase Whitener ", + "CONFIGURE_REQUIRES" => { + "ExtUtils::MakeMaker" => 0 + }, + "DISTNAME" => "Exceptions", + "LICENSE" => "perl", + "NAME" => "Exceptions", + "PREREQ_PM" => { + "strict" => 0, + "warnings" => 0 + }, + "TEST_REQUIRES" => { + "ExtUtils::MakeMaker" => 0, + "File::Spec" => 0, + "Test::More" => "0.88" + }, + "VERSION" => "0.100", + "test" => { + "TESTS" => "t/*.t" + } +); + + +my %FallbackPrereqs = ( + "ExtUtils::MakeMaker" => 0, + "File::Spec" => 0, + "Test::More" => "0.88", + "strict" => 0, + "warnings" => 0 +); + + +unless ( eval { ExtUtils::MakeMaker->VERSION(6.63_03) } ) { + delete $WriteMakefileArgs{TEST_REQUIRES}; + delete $WriteMakefileArgs{BUILD_REQUIRES}; + $WriteMakefileArgs{PREREQ_PM} = \%FallbackPrereqs; +} + +delete $WriteMakefileArgs{CONFIGURE_REQUIRES} + unless eval { ExtUtils::MakeMaker->VERSION(6.52) }; + +WriteMakefile(%WriteMakefileArgs); diff --git a/README.md b/README.md new file mode 100644 index 0000000..c48e79f --- /dev/null +++ b/README.md @@ -0,0 +1,168 @@ +# NAME + +Exceptions - Documentation for exception handling in Perl. + +# DESCRIPTION + +This module doesn't do anything, it exists solely to document how to handle +exceptions in Perl. + +# WHY? + +This module was originally released in 1996, but it hasn't been installable or +usable in any fashion since then. Many other alternatives have cropped up over +the years to make exception handling much easier. If you want to skip the +explanations below, then you should look directly at some of the modules that +make exception handling dead-simple: + +[Try::Tiny](https://metacpan.org/pod/Try::Tiny) - Catch exceptions in a familiar `try` and `catch` way. If you +look no further, make use of this module! + +With a good way to catch exceptions, now you need exception types so you can +re-throw exceptions when they're something that should be handled elsewhere. + +- [Throwable](https://metacpan.org/pod/Throwable) and [Throwable::SugarFactory](https://metacpan.org/pod/Throwable::SugarFactory) +- [Exception::Class](https://metacpan.org/pod/Exception::Class) +- [Mojo::Exception](https://metacpan.org/pod/Mojo::Exception) + +# AN EXCEPTION + +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; + } + +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 +from doing any further execution. So, we must handle our exceptions! + +# A HANDLED EXCEPTION + +The only way you can handle an exception is to wrap the code that could +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 +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; + + my $value; + my $error = do { # catch block + local $@; + eval { $value = increment(0) }; # try + $@; + }; + + print "0 plus 1 = "; + if ($error) { + print "error"; + } + else { + print $value; + } + print "\n"; # 1 + + $value = undef; + $error = undef; + $error = do { # catch block + local $@; + eval { $value = increment('zero') }; # try + $@; + }; + + print "zero plus 1 = "; + if ($error) { + print "error"; + } + else { + print $value; + } + print "\n"; # error + + $value = undef; + $error = undef; + $error = do { # catch block + local $@; + eval { $value = increment(0) }; # try + $@; + }; + + print "0 plus 1 = "; + if ($error) { + print "error"; + } + else { + print $value; + } + print "\n"; # 1 + + 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! + +# THE SOLUTION + +Lucky for us, Perl is an awesome language where the community provides many +solutions to common tasks for us. One such solution is [Try::Tiny](https://metacpan.org/pod/Try::Tiny). + +If you get nothing else out of this document, let it be that using [Try::Tiny](https://metacpan.org/pod/Try::Tiny) +will save you time and heartache. + + #!/usr/bin/env perl + use strict; + use warnings; + use Try::Tiny qw(try catch); + + print "0 plus 1 = ", try { increment(0) } catch { "error" }; + print "\n"; # 1 + + print "zero plus 1 = ", try { increment('zero') } catch { "error" }; + print "\n"; # error + + print "0 plus 1 = ", try { increment(0) } catch { "error" }; + print "\n"; # 1 + + sub increment { + my $int = shift; + die "That's not an int!" unless defined $int && $int =~ /^[0-9]+\z/; + return $int+1; + } + +# AUTHOR + +Chase Whitener <`capoeirab@cpan.org`> + +# LICENSE AND COPYRIGHT + +Copyright 1996 by Peter Seibel <`pseibel@cpan.org`>. This original release +was made without an attached license. + +Copyright 2016 by Chase Whitener <`capoeirab@cpan.org`>. This re-release contains +none of the original code or structure and is thus re-released under the same +license as Perl itself. + +This program is free software; you can redistribute it and/or modify +it under the same terms as Perl itself. diff --git a/cpanfile b/cpanfile new file mode 100644 index 0000000..063de3b --- /dev/null +++ b/cpanfile @@ -0,0 +1,15 @@ +on 'runtime' => sub { + requires 'strict'; + requires 'warnings'; +}; + +on 'test' => sub { + requires 'Test::More' => '0.88'; +}; + +on 'develop' => sub { + requires 'Test::CheckManifest' => '1.29'; + requires 'Test::CPAN::Changes' => '0.4'; + requires 'Test::Kwalitee' => '1.22'; + requires 'Test::Pod::Spelling::CommonMistakes' => '1.000'; +}; diff --git a/dist.ini b/dist.ini new file mode 100644 index 0000000..c285b2e --- /dev/null +++ b/dist.ini @@ -0,0 +1,50 @@ +name = Exceptions +author = Chase Whitener +license = Perl_5 +copyright_holder = Chase Whitener +copyright_year = 2016 + +version = 0.100 + +[@Starter] +revision = 1 +ReadmeAnyFromPod.source_filename = lib/Exceptions.pm +GatherDir.exclude_filename[0] = Makefile.PL +GatherDir.exclude_filename[1] = META.json +GatherDir.exclude_filename[2] = README.md + +[ReadmeAnyFromPod / Markdown_Readme] +type = markdown +filename = README.md +location = root + +[Prereqs::FromCPANfile] +[MetaProvides::Package] + +[NextRelease] +format = %-9v %{yyyy-MM-dd}d + +[Git::Contributors] +[GithubMeta] +issues = 1 +user = genio +[@Git] + +[CheckChangeLog] +[CheckChangesHasContent] +[Test::ChangesHasContent] +[PkgVersion] + +[Test::Kwalitee] +[Test::Version] +[Test::Pod::Coverage::Configurable] + +[Test::PodSpelling] +wordlist = Pod::Wordlist +spell_cmd = aspell list +stopword = Seibel + +[CopyFilesFromBuild] +copy = Makefile.PL +copy = META.json +copy = README.md diff --git a/lib/Exception.pm b/lib/Exception.pm new file mode 100644 index 0000000..e44a6ba --- /dev/null +++ b/lib/Exception.pm @@ -0,0 +1,37 @@ +package Exception; + +use strict; +use warnings; + +1; + +__END__ + +=head1 NAME + +Exception - Placeholder. + +=head1 DESCRIPTION + +This is a simple placeholder for an older module that was released that is no +longer available. + +See L for information. + +=head1 AUTHOR + +Chase Whitener > + +=head1 LICENSE AND COPYRIGHT + +Copyright 1996 by Peter Seibel >. This original release +was made without an attached license. + +Copyright 2016 by Chase Whitener >. This re-release contains +none of the original code or structure and is thus re-released under the same +license as Perl itself. + +This program is free software; you can redistribute it and/or modify +it under the same terms as Perl itself. + +=cut diff --git a/lib/Exceptions.pm b/lib/Exceptions.pm new file mode 100644 index 0000000..73ca898 --- /dev/null +++ b/lib/Exceptions.pm @@ -0,0 +1,192 @@ +package Exceptions; + +use strict; +use warnings; + +1; + +__END__ + +=head1 NAME + +Exceptions - Documentation for exception handling in Perl. + +=head1 DESCRIPTION + +This module doesn't do anything, it exists solely to document how to handle +exceptions in Perl. + +=head1 WHY? + +This module was originally released in 1996, but it hasn't been installable or +usable in any fashion since then. Many other alternatives have cropped up over +the years to make exception handling much easier. If you want to skip the +explanations below, then you should look directly at some of the modules that +make exception handling dead-simple: + +L - Catch exceptions in a familiar C and C way. If you +look no further, make use of this module! + +With a good way to catch exceptions, now you need exception types so you can +re-throw exceptions when they're something that should be handled elsewhere. + +=over + +=item * + +L and L + +=item * + +L + +=item * + +L + +=back + + +=head1 AN EXCEPTION + +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; + } + +The first line prints C<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 +from doing any further execution. So, we must handle our exceptions! + +=head1 A HANDLED EXCEPTION + +The only way you can handle an exception is to wrap the code that could +die in an C 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 C<$@> variable. Please see L for a +great explanation of this problem. + +Let's look at our previous simple application with error handling using C. + + #!/usr/bin/env perl + use strict; + use warnings; + + my $value; + my $error = do { # catch block + local $@; + eval { $value = increment(0) }; # try + $@; + }; + + print "0 plus 1 = "; + if ($error) { + print "error"; + } + else { + print $value; + } + print "\n"; # 1 + + $value = undef; + $error = undef; + $error = do { # catch block + local $@; + eval { $value = increment('zero') }; # try + $@; + }; + + print "zero plus 1 = "; + if ($error) { + print "error"; + } + else { + print $value; + } + print "\n"; # error + + $value = undef; + $error = undef; + $error = do { # catch block + local $@; + eval { $value = increment(0) }; # try + $@; + }; + + print "0 plus 1 = "; + if ($error) { + print "error"; + } + else { + print $value; + } + print "\n"; # 1 + + 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! + +=head1 THE SOLUTION + +Lucky for us, Perl is an awesome language where the community provides many +solutions to common tasks for us. One such solution is L. + +If you get nothing else out of this document, let it be that using L +will save you time and heartache. + + #!/usr/bin/env perl + use strict; + use warnings; + use Try::Tiny qw(try catch); + + print "0 plus 1 = ", try { increment(0) } catch { "error" }; + print "\n"; # 1 + + print "zero plus 1 = ", try { increment('zero') } catch { "error" }; + print "\n"; # error + + print "0 plus 1 = ", try { increment(0) } catch { "error" }; + print "\n"; # 1 + + sub increment { + my $int = shift; + die "That's not an int!" unless defined $int && $int =~ /^[0-9]+\z/; + return $int+1; + } + +=head1 AUTHOR + +Chase Whitener > + +=head1 LICENSE AND COPYRIGHT + +Copyright 1996 by Peter Seibel >. This original release +was made without an attached license. + +Copyright 2016 by Chase Whitener >. This re-release contains +none of the original code or structure and is thus re-released under the same +license as Perl itself. + +This program is free software; you can redistribute it and/or modify +it under the same terms as Perl itself. + +=cut diff --git a/lib/SimpleException.pm b/lib/SimpleException.pm new file mode 100644 index 0000000..f235c76 --- /dev/null +++ b/lib/SimpleException.pm @@ -0,0 +1,37 @@ +package SimpleException; + +use strict; +use warnings; + +1; + +__END__ + +=head1 NAME + +SimpleException - Placeholder. + +=head1 DESCRIPTION + +This is a simple placeholder for an older module that was released that is no +longer available. + +See L for information. + +=head1 AUTHOR + +Chase Whitener > + +=head1 LICENSE AND COPYRIGHT + +Copyright 1996 by Peter Seibel >. This original release +was made without an attached license. + +Copyright 2016 by Chase Whitener >. This re-release contains +none of the original code or structure and is thus re-released under the same +license as Perl itself. + +This program is free software; you can redistribute it and/or modify +it under the same terms as Perl itself. + +=cut diff --git a/t/01-use.t b/t/01-use.t new file mode 100644 index 0000000..0e0bdd5 --- /dev/null +++ b/t/01-use.t @@ -0,0 +1,13 @@ +#!perl + +use strict; +use warnings; +use Test::More 0.88; # done_testing() + +BEGIN { + use_ok('Exceptions') or BAIL_OUT("Can't use module"); + use_ok('Exception') or BAIL_OUT("Can't use module"); + use_ok('SimpleException') or BAIL_OUT("Can't use module"); +} + +done_testing();