r44247 - in /branches/upstream/libtry-tiny-perl: ./ current/ current/lib/ current/lib/Try/ current/t/

ansgar-guest at users.alioth.debian.org ansgar-guest at users.alioth.debian.org
Fri Sep 18 18:30:42 UTC 2009


Author: ansgar-guest
Date: Fri Sep 18 18:30:27 2009
New Revision: 44247

URL: http://svn.debian.org/wsvn/pkg-perl/?sc=1&rev=44247
Log:
[svn-inject] Installing original source of libtry-tiny-perl

Added:
    branches/upstream/libtry-tiny-perl/
    branches/upstream/libtry-tiny-perl/current/
    branches/upstream/libtry-tiny-perl/current/Changes
    branches/upstream/libtry-tiny-perl/current/MANIFEST
    branches/upstream/libtry-tiny-perl/current/MANIFEST.SKIP
    branches/upstream/libtry-tiny-perl/current/META.yml
    branches/upstream/libtry-tiny-perl/current/Makefile.PL
    branches/upstream/libtry-tiny-perl/current/SIGNATURE
    branches/upstream/libtry-tiny-perl/current/lib/
    branches/upstream/libtry-tiny-perl/current/lib/Try/
    branches/upstream/libtry-tiny-perl/current/lib/Try/Tiny.pm
    branches/upstream/libtry-tiny-perl/current/t/
    branches/upstream/libtry-tiny-perl/current/t/basic.t
    branches/upstream/libtry-tiny-perl/current/t/when.t

Added: branches/upstream/libtry-tiny-perl/current/Changes
URL: http://svn.debian.org/wsvn/pkg-perl/branches/upstream/libtry-tiny-perl/current/Changes?rev=44247&op=file
==============================================================================
--- branches/upstream/libtry-tiny-perl/current/Changes (added)
+++ branches/upstream/libtry-tiny-perl/current/Changes Fri Sep 18 18:30:27 2009
@@ -1,0 +1,8 @@
+0.02
+	- Doc fixes from chromatic
+	- Various minor fixes from Adam Kennedy
+	- Additional documentation and code clarifications
+	- 5.005_04 compatibility
+
+0.01
+	- Initial release

Added: branches/upstream/libtry-tiny-perl/current/MANIFEST
URL: http://svn.debian.org/wsvn/pkg-perl/branches/upstream/libtry-tiny-perl/current/MANIFEST?rev=44247&op=file
==============================================================================
--- branches/upstream/libtry-tiny-perl/current/MANIFEST (added)
+++ branches/upstream/libtry-tiny-perl/current/MANIFEST Fri Sep 18 18:30:27 2009
@@ -1,0 +1,9 @@
+Changes
+lib/Try/Tiny.pm
+Makefile.PL
+MANIFEST			This list of files
+MANIFEST.SKIP
+t/basic.t
+t/when.t
+META.yml                                 Module meta-data (added by MakeMaker)
+SIGNATURE                                Public-key signature (added by MakeMaker)

Added: branches/upstream/libtry-tiny-perl/current/MANIFEST.SKIP
URL: http://svn.debian.org/wsvn/pkg-perl/branches/upstream/libtry-tiny-perl/current/MANIFEST.SKIP?rev=44247&op=file
==============================================================================
--- branches/upstream/libtry-tiny-perl/current/MANIFEST.SKIP (added)
+++ branches/upstream/libtry-tiny-perl/current/MANIFEST.SKIP Fri Sep 18 18:30:27 2009
@@ -1,0 +1,46 @@
+# Avoid version control files.
+\bRCS\b
+\bCVS\b
+\bSCCS\b
+,v$
+\B\.svn\b
+\B\.git\b
+\b_darcs\b
+
+# Avoid Makemaker generated and utility files.
+\bMANIFEST\.bak
+\bMakefile$
+\bblib/
+\bMakeMaker-\d
+\bpm_to_blib\.ts$
+\bpm_to_blib$
+\bblibdirs\.ts$         # 6.18 through 6.25 generated this
+
+# Avoid Module::Build generated and utility files.
+\bBuild$
+\b_build/
+
+# Avoid temp and backup files.
+~$
+\.old$
+\#$
+\b\.#
+\.bak$
+
+# Avoid Devel::Cover files.
+\bcover_db\b
+
+### DEFAULT MANIFEST.SKIP ENDS HERE ####
+
+\.DS_Store$
+\.sw.$
+(\w+-)*(\w+)-\d\.\d+(?:\.tar\.gz)?$
+
+\.t\.log$
+
+\.prove$
+
+# XS shit
+\.(?:bs|c|o)$
+
+\.gitignore$

Added: branches/upstream/libtry-tiny-perl/current/META.yml
URL: http://svn.debian.org/wsvn/pkg-perl/branches/upstream/libtry-tiny-perl/current/META.yml?rev=44247&op=file
==============================================================================
--- branches/upstream/libtry-tiny-perl/current/META.yml (added)
+++ branches/upstream/libtry-tiny-perl/current/META.yml Fri Sep 18 18:30:27 2009
@@ -1,0 +1,13 @@
+--- #YAML:1.0
+name:                Try-Tiny
+version:             0.02
+abstract:            ~
+license:             ~
+author:              ~
+generated_by:        ExtUtils::MakeMaker version 6.42
+distribution_type:   module
+requires:     
+    Test::More:                    0
+meta-spec:
+    url:     http://module-build.sourceforge.net/META-spec-v1.3.html
+    version: 1.3

Added: branches/upstream/libtry-tiny-perl/current/Makefile.PL
URL: http://svn.debian.org/wsvn/pkg-perl/branches/upstream/libtry-tiny-perl/current/Makefile.PL?rev=44247&op=file
==============================================================================
--- branches/upstream/libtry-tiny-perl/current/Makefile.PL (added)
+++ branches/upstream/libtry-tiny-perl/current/Makefile.PL Fri Sep 18 18:30:27 2009
@@ -1,0 +1,16 @@
+use strict;
+
+use ExtUtils::MakeMaker;
+
+require 5.005_04;
+
+WriteMakefile(
+	NAME         => 'Try::Tiny',
+	VERSION_FROM => 'lib/Try/Tiny.pm',
+	INSTALLDIRS  => 'site',
+	SIGN         => 1,
+	PL_FILES     => { },
+	PREREQ_PM    => {
+		'Test::More' => 0,
+	},
+);

Added: branches/upstream/libtry-tiny-perl/current/SIGNATURE
URL: http://svn.debian.org/wsvn/pkg-perl/branches/upstream/libtry-tiny-perl/current/SIGNATURE?rev=44247&op=file
==============================================================================
--- branches/upstream/libtry-tiny-perl/current/SIGNATURE (added)
+++ branches/upstream/libtry-tiny-perl/current/SIGNATURE Fri Sep 18 18:30:27 2009
@@ -1,0 +1,31 @@
+This file contains message digests of all files listed in MANIFEST,
+signed via the Module::Signature module, version 0.55.
+
+To verify the content in this distribution, first make sure you have
+Module::Signature installed, then type:
+
+    % cpansign -v
+
+It will check each file's integrity, as well as the signature's
+validity.  If "==> Signature verified OK! <==" is not displayed,
+the distribution may already have been compromised, and you should
+not run its Makefile.PL or Build.PL.
+
+-----BEGIN PGP SIGNED MESSAGE-----
+Hash: SHA1
+
+SHA1 d150077b59fe9b327023d1b32e746c8fff661983 Changes
+SHA1 0f7f01d0d9d133529eccfe396cf4c71a37a197ad MANIFEST
+SHA1 606bd6424682249397d63caf905f651178a4d6cc MANIFEST.SKIP
+SHA1 85e16f502eb5ec72cccd91a8e25fdaf4fe88a3e1 META.yml
+SHA1 6adc37b24473f070c318abfe77a8531fbf1eefca Makefile.PL
+SHA1 10edc1903fdbc5a81a28b05a5a33ce3da9bc11bb lib/Try/Tiny.pm
+SHA1 85cdb50e91e46c74bdff5a3c147655e060190c76 t/basic.t
+SHA1 c75ffed79f4936105b81aa82443b0a0a87c78873 t/when.t
+-----BEGIN PGP SIGNATURE-----
+Version: GnuPG v1.4.7 (Darwin)
+
+iD8DBQFKnq77VCwRwOvSdBgRAnU4AJ9TFIkNbNVAWKADeeH2E5Ug4lyC7gCfeoZu
+Bh881ePwvmPrrFSNPhgVlhM=
+=vbpJ
+-----END PGP SIGNATURE-----

Added: branches/upstream/libtry-tiny-perl/current/lib/Try/Tiny.pm
URL: http://svn.debian.org/wsvn/pkg-perl/branches/upstream/libtry-tiny-perl/current/lib/Try/Tiny.pm?rev=44247&op=file
==============================================================================
--- branches/upstream/libtry-tiny-perl/current/lib/Try/Tiny.pm (added)
+++ branches/upstream/libtry-tiny-perl/current/lib/Try/Tiny.pm Fri Sep 18 18:30:27 2009
@@ -1,0 +1,339 @@
+package Try::Tiny;
+
+use strict;
+#use warnings;
+
+use vars qw(@EXPORT @EXPORT_OK $VERSION @ISA);
+
+BEGIN {
+	require Exporter;
+	@ISA = qw(Exporter);
+}
+
+$VERSION = "0.02";
+
+$VERSION = eval $VERSION;
+
+ at EXPORT = @EXPORT_OK = qw(try catch);
+
+sub try (&;$) {
+	my ( $try, $catch ) = @_;
+
+	# we need to save this here, the eval block will be in scalar context due
+	# to $failed
+	my $wantarray = wantarray;
+
+	my ( @ret, $error, $failed );
+
+	# FIXME consider using local $SIG{__DIE__} to accumilate all errors. It's
+	# not perfect, but we could provide a list of additional errors for
+	# $catch->();
+
+	{
+		# localize $@ to prevent clobbering of previous value by a successful
+		# eval.
+		local $@;
+
+		# failed will be true if the eval dies, because 1 will not be returned
+		# from the eval body
+		$failed = not eval {
+
+			# evaluate the try block in the correct context
+			if ( $wantarray ) {
+				@ret = $try->();
+			} elsif ( defined $wantarray ) {
+				$ret[0] = $try->();
+			} else {
+				$try->();
+			};
+
+			return 1; # properly set $fail to false
+		};
+
+		# copy $@ to $error, when we leave this scope local $@ will revert $@
+		# back to its previous value
+		$error = $@;
+	}
+
+	# at this point $failed contains a true value if the eval died even if some
+	# destructor overwrite $@ as the eval was unwinding.
+	if ( $failed ) {
+		# if we got an error, invoke the catch block.
+		if ( $catch ) {
+			# This works like given($error), but is backwards compatible and
+			# sets $_ in the dynamic scope for the body of C<$catch>
+			for ($error) {
+				return $catch->($error);
+			}
+
+			# in case when() was used without an explicit return, the C<for>
+			# loop will be aborted and there's no useful return value
+		}
+
+		return;
+	} else {
+		# no failure, $@ is back to what it was, everything is fine
+		return $wantarray ? @ret : $ret[0];
+	}
+}
+
+sub catch (&) {
+	return $_[0];
+}
+
+
+__PACKAGE__
+
+__END__
+
+=pod
+
+=head1 NAME
+
+Try::Tiny - minimal try/catch with proper localization of $@
+
+=head1 SYNOPSIS
+
+	# handle errors with a catch handler
+	try {
+		die "foo";
+	} catch {
+		warn "caught error: $_";
+	};
+
+	# just silence errors
+	try {
+		die "foo";
+	};
+
+=head1 DESCRIPTION
+
+This module provides bare bones C<try>/C<catch> statements that are designed to
+minimize common mistakes with eval blocks, and NOTHING else.
+
+This is unlike L<TryCatch> which provides a nice syntax and avoids adding
+another call stack layer, and supports calling C<return> from the try block to
+return from the parent subroutine. These extra features come at a cost of a few
+dependencies, namely L<Devel::Declare> and L<Scope::Upper> which are
+occasionally problematic, and the additional catch filtering uses L<Moose>
+type constraints which may not be desirable either.
+
+The main focus of this module is to provide simple and reliable error handling
+for those having a hard time installing L<TryCatch>, but who still want to
+write correct C<eval> blocks without 5 lines of boilerplate each time.
+
+It's designed to work as correctly as possible in light of the various
+pathological edge cases (see L<BACKGROUND>) and to be compatible with any style
+of error values (simple strings, references, objects, overloaded objects, etc).
+
+=head1 EXPORTS
+
+All functions are exported by default using L<Exporter>.
+
+In the future L<Sub::Exporter> may be used to allow the keywords to be renamed,
+but this technically does not satisfy Adam Kennedy's definition of "Tiny".
+
+=over 4
+
+=item try (&;$)
+
+Takes one mandatory try subroutine and one optional catch subroutine.
+
+The mandatory subroutine is evaluated in the context of an C<eval> block.
+
+If no error occurred the value from the first block is returned, preserving
+list/scalar context.
+
+If there was an error and the second subroutine was given it will be invoked
+with the error in C<$_> (localized) and as that block's first and only
+argument.
+
+Note that the error may be false, but if that happens the C<catch> block will
+still be invoked..
+
+=item catch (&)
+
+Intended to be used in the second argument position of C<try>.
+
+Just returns the subroutine it was given.
+
+	catch { ... }
+
+is the same as
+
+	sub { ... }
+
+=back
+
+=head1 BACKGROUND
+
+There are a number of issues with C<eval>.
+
+=head2 Clobbering $@
+
+When you run an eval block and it succeeds, C<$@> will be cleared, potentially
+clobbering an error that is currently being caught.
+
+This causes action at a distance, clearing previous errors your caller may have
+not yet handled.
+
+C<$@> must be properly localized before invoking C<eval> in order to avoid this
+issue.
+
+=head2 Localizing $@ silently masks errors
+
+Inside an eval block C<die> behaves sort of like:
+
+	sub die {
+		$@_ = $_[0];
+		return_undef_from_eval();
+	}
+
+This means that if you were polite and localized C<$@> you can't die in that
+scope, or your error will be discarded (printing "Something's wrong" instead).
+
+The workaround is very ugly:
+
+	my $error = do {
+		local $@;
+		eval { ... };
+		$@;
+	};
+
+	...
+	die $error;
+
+=head2 $@ might not be a true value
+
+This code is wrong:
+
+	if ( $@ ) {
+		...
+	}
+
+because due to the previous caveats it may have been unset.
+
+C<$@> could also an overloaded error object that evaluates to false, but that's
+asking for trouble anyway.
+
+The classic failure mode is:
+
+	sub Object::DESTROY {
+		eval { ... }
+	}
+
+	eval {
+		my $obj = Object->new;
+
+		die "foo";
+	};
+
+	if ( $@ ) {
+
+	}
+
+In this case since C<Object::DESTROY> is not localizing C<$@> but still uses
+C<eval> it will set C<$@> to C<"">.
+
+The destructor is called when the stack is unwound, after C<die> sets C<$@> to
+C<"foo at Foo.pm line 42\n">, so by the time C<if ( $@ )> is evaluated it has
+been cleared by C<eval> in the destructor.
+
+The workaround for this is even uglier than the previous ones. Even though we
+can't save the value of C<$@> from code that doesn't localize, we can at least
+be sure the eval was aborted due to an error:
+
+	my $failed = not eval {
+		...
+
+		return 1;
+	};
+
+This is because an C<eval> that caught a C<die> will always return a false
+value.
+
+=head1 SHINY SYNTAX
+
+Using Perl 5.10 you can use L<perlsyn/"Switch statements">.
+
+The C<catch> block is invoked in a topicalizer context (like a C<given> block),
+but note that you can't return a useful value from C<catch> using the C<when>
+blocks without an explicit C<return>.
+
+This is somewhat similar to Perl 6's C<CATCH> blocks. You can use it to
+concisely match errors:
+
+	try {
+		require Foo;
+	} catch {
+		when (/^Can't locate .*?\.pm in \@INC/) { } # ignore
+		default { die $_ }
+	};
+
+=head1 CAVEATS
+
+=over 4
+
+=item *
+
+C<try> introduces another caller stack frame. L<Sub::Uplevel> is not used. L<Carp>
+will report this when using full stack traces. This lack of magic is considered
+a feature.
+
+=item *
+
+The value of C<$_> in the C<catch> block is not guaranteed to be preserved,
+there is no safe way to ensure this if C<eval> is used unhygenically in
+destructors. It's only guaranteeed that the C<catch> will be called.
+
+=back
+
+=head1 SEE ALSO
+
+=over 4
+
+=item L<TryCatch>
+
+Much more feature complete, more convenient semantics, but at the cost of
+implementation complexity.
+
+=item L<autodie>
+
+Automatic error throwing for builtin functions and more. Also designed to
+work well with C<given>/C<when>.
+
+=item L<Throwable>
+
+A lightweight role for rolling your own exception classes.
+
+=item L<Error>
+
+Exception object implementation with a C<try> statement. Does not localize
+C<$@>.
+
+=item L<Exception::Class::TryCatch>
+
+Provides a C<catch> statement, but properly calling C<eval> is your
+responsibility.
+
+The C<try> keyword pushes C<$@> onto an error stack, avoiding some of the
+issues with C<$@> but you still need to localize to prevent clobbering.
+
+=back
+
+=head1 VERSION CONTROL
+
+L<http://github.com/nothingmuch/try-tiny/>
+
+=head1 AUTHOR
+
+Yuval Kogman E<lt>nothingmuch at woobling.orgE<gt>
+
+=head1 COPYRIGHT
+
+	Copyright (c) 2009 Yuval Kogman. All rights reserved.
+	This program is free software; you can redistribute
+	it and/or modify it under the terms of the MIT license.
+
+=cut
+

Added: branches/upstream/libtry-tiny-perl/current/t/basic.t
URL: http://svn.debian.org/wsvn/pkg-perl/branches/upstream/libtry-tiny-perl/current/t/basic.t?rev=44247&op=file
==============================================================================
--- branches/upstream/libtry-tiny-perl/current/t/basic.t (added)
+++ branches/upstream/libtry-tiny-perl/current/t/basic.t Fri Sep 18 18:30:27 2009
@@ -1,0 +1,99 @@
+#!/usr/bin/perl
+
+use strict;
+#use warnings;
+
+use Test::More tests => 15;
+
+BEGIN { use_ok 'Try::Tiny' };
+
+sub _eval {
+	local $@;
+	local $Test::Builder::Level = $Test::Builder::Level + 2;
+	return ( scalar(eval { $_[0]->(); 1 }), $@ );
+}
+
+
+sub lives_ok (&$) {
+	my ( $code, $desc ) = @_;
+	local $Test::Builder::Level = $Test::Builder::Level + 1;
+
+	my ( $ok, $error ) = _eval($code);
+
+	ok($ok, $desc );
+
+	diag "error: $@" unless $ok;
+}
+
+sub throws_ok (&$$) {
+	my ( $code, $regex, $desc ) = @_;
+	local $Test::Builder::Level = $Test::Builder::Level + 1;
+
+	my ( $ok, $error ) = _eval($code);
+
+	if ( $ok ) {
+		fail($desc);
+	} else {
+		like($error || '', $regex, $desc );
+	}
+}
+
+
+lives_ok {
+	try {
+		die "foo";
+	};
+} "basic try";
+
+throws_ok {
+	try {
+		die "foo";
+	} catch { die $_ };
+} qr/foo/, "rethrow";
+
+
+{
+	local $@ = "magic";
+	is( try { 42 }, 42, "try block evaluated" );
+	is( $@, "magic", '$@ untouched' );
+}
+
+{
+	local $@ = "magic";
+	is( try { die "foo" }, undef, "try block died" );
+	is( $@, "magic", '$@ untouched' );
+}
+
+{
+	local $@ = "magic";
+	like( (try { die "foo" } catch { $_ }), qr/foo/, "catch block evaluated" );
+	is( $@, "magic", '$@ untouched' );
+}
+
+is( scalar(try { "foo", "bar", "gorch" }), "gorch", "scalar context" );
+is_deeply( [ try {qw(foo bar gorch)} ], [qw(foo bar gorch)], "list context" );
+
+
+
+sub Evil::DESTROY {
+	eval { "oh noes" };
+}
+
+sub Evil::new { bless { }, $_[0] }
+
+{
+	local $@ = "magic";
+	local $_ = "other magic";
+
+	try {
+		my $object = Evil->new;
+		die "foo";
+	} catch {
+		pass("catch invoked");
+		local $TODO = "i don't think we can ever make this work sanely, maybe with SIG{__DIE__}";
+		like($_, qr/foo/);
+	};
+
+	is( $@, "magic", '$@ untouched' );
+	is( $_, "other magic", '$_ untouched' );
+}

Added: branches/upstream/libtry-tiny-perl/current/t/when.t
URL: http://svn.debian.org/wsvn/pkg-perl/branches/upstream/libtry-tiny-perl/current/t/when.t?rev=44247&op=file
==============================================================================
--- branches/upstream/libtry-tiny-perl/current/t/when.t (added)
+++ branches/upstream/libtry-tiny-perl/current/t/when.t Fri Sep 18 18:30:27 2009
@@ -1,0 +1,37 @@
+#!/usr/bin/perl
+
+use strict;
+#use warnings;
+
+use Test::More;
+
+BEGIN {
+	plan skip_all => "Perl 5.10 required" unless eval { require 5.010; 1 };
+	plan tests => 6;
+}
+
+
+BEGIN { use_ok 'Try::Tiny' }
+
+use 5.010;
+
+my ( $foo, $bar, $other );
+
+$_ = "magic";
+
+try {
+	die "foo";
+} catch {
+
+	like( $_, qr/foo/ );
+
+	when (/bar/) { $bar++ };
+	when (/foo/) { $foo++ };
+	default { $other++ };
+};
+
+is( $_, "magic", '$_ not clobbered' );
+
+ok( !$bar, "bar didn't match" );
+ok( $foo, "foo matched" );
+ok( !$other, "fallback didn't match" );




More information about the Pkg-perl-cvs-commits mailing list