Skip to content

Commit

Permalink
Improved line and pagebreaking for chapter 8.
Browse files Browse the repository at this point in the history
  • Loading branch information
chromatic committed Dec 8, 2011
1 parent 456d6fe commit 337f583
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 29 deletions.
50 changes: 31 additions & 19 deletions sections/exceptions.pod
Original file line number Diff line number Diff line change
Expand Up @@ -80,8 +80,9 @@ X<magic variables; C<$@>>

An exception handler is a blunt tool. It will catch all exceptions in its
dynamic scope. To check which exception you've caught (or if you've caught an
exception at all), check the value of C<$@>. As C<$@> is a I<global> variable,
you should C<local>ize it before you attempt to catch an exception:
exception at all), check the value of C<$@>. Be sure to C<local>ize C<$@>
before you attempt to catch an exception; remember that C<$@> is a global
variable:

=begin programlisting

Expand All @@ -101,14 +102,15 @@ Copy C<$@> to a lexical variable immediately to avoid the possibility of
subsequent code clobbering the global variable C<$@>. You never know what else
has used an C<eval> block elsewhere and reset C<$@>.

C<$@> usually contains a string describing the exception. You can inspect its
contents to see whether you can handle the exception:
C<$@> usually contains a string describing the exception. Inspect its contents
to see whether you can handle the exception:

=begin programlisting

if (my $exception = $@)
{
die $exception unless $exception =~ /^Can't open logging file/;
die $exception
unless $exception =~ /^Can't open logging/;
$fh = log_to_syslog();
}

Expand All @@ -118,15 +120,20 @@ Rethrow an exception by calling C<die()> again. Pass the existing exception or
a new one as necessary.

X<exceptions; throwing objects>

Applying regular expressions to string exceptions can be fragile, because error
messages may change over time. This includes the core exceptions that Perl
itself throws. Fortunately, you may also provide a reference--even a blessed
reference--to C<die>. This allows you to provide much more information in your
exception: line numbers, files, and other debugging information. Retrieving
this information from something structured is much easier than parsing it out
of a string. Catch these exceptions as you would any other exception.

X<exceptions; custom classes with C<Exception::Class>>
X<C<Exception::Class>>

You may C<die> with either a string or a reference--even an I<object>. Applying
regular expressions to string exceptions can be fragile, because error messages
may change over time, even those built from Perl itself. Objects are more
robust; they contain more information. You can throw any object as an
exception, but consider using the CPAN distribution C<Exception::Class> to
define your own class or classes of exceptions:
The CPAN distribution C<Exception::Class> makes creating and using exception
objects easy:

=begin programlisting

Expand All @@ -140,27 +147,28 @@ define your own class or classes of exceptions:
sub cage_open
{
my $self = shift;
Zoo::AnimalEscaped->throw unless $self->contains_animal;
Zoo::AnimalEscaped->throw
unless $self->contains_animal;
...
}

sub breakroom_open
{
my $self = shift;
Zoo::HandlerEscaped->throw unless $self->contains_handler;
Zoo::HandlerEscaped->throw
unless $self->contains_handler;
...
}

=end programlisting

Catch these exceptions as you would any other exception.

=head2 Exception Caveats

Z<exception_caveats>

X<exceptions; caveats>

Though throwing exceptions is relatively simple, catching them is less so.
Using C<$@> correctly requires you to navigate several subtle risks:

=over 4
Expand All @@ -181,16 +189,20 @@ change C<$@>
X<exceptions; handling safely with C<Try::Tiny>>
X<C<Try::Tiny>>

Perl 5.14 improves the safety of exception handling. The C<Try::Tiny> CPAN
distribution improves the safety of exception handling I<and> the syntax. It's
easy to use:
Perl 5.14 fixed some of these issues. Granted, they occur very rarely, but
they're often difficult to diagnose and to fix. The C<Try::Tiny> CPAN
distribution improves the safety of exception handling I<and> the syntaxN<In
fact, C<Try::Tiny> helped inspire improvements to Perl 5.14's exception
handling.>.

C<Try::Tiny> is easy to use:

=begin programlisting

use Try::Tiny;

my $fh = try { open_log_file( 'monkeytown.log' ) }
catch { log_exception( "Something went wrong: '$_'" };
catch { log_exception( $_ ) };

=end programlisting

Expand Down
24 changes: 15 additions & 9 deletions sections/pragmas.pod
Original file line number Diff line number Diff line change
Expand Up @@ -15,22 +15,22 @@ modules.

X<pragmas; scope>

Pragmas work by exporting specific behavior or information into their caller
scopes--lexical scopes. Just as declaring a lexical variable makes a symbol
Pragmas work by exporting specific behavior or information into the lexical
scopes of their callers. Just as declaring a lexical variable makes a symbol
name available within a scope, using a pragma makes its behavior effective
within that scope:

=begin programlisting

{
# $lexical is B<not> visible; strict is B<not> in effect
# $lexical B<not> visible; strict B<not> in effect
{
use strict;
my $lexical = 'available here';
# $lexical B<is> visible; strict B<is> in effect
...
}
# $lexical is again B<not> visible; strict is B<not> in effect
# $lexical again invisible; strict B<not> in effect
}

=end programlisting
Expand Down Expand Up @@ -61,16 +61,21 @@ behavior:

=begin programlisting

# require variable declarations; prohibit bareword function names
# require variable declarations, prohibit barewords
use strict qw( subs vars );

=end programlisting

X<pragmas; disabling>
X<builtins; C<no>>

Disable all or part of a pragma with the C<no> builtin. This also respects
lexical scoping:
Pragmas have lexical effects, and sometimes you need to I<disable> all or part
of those effects within a further nested lexical scope. The C<no> builtin
performs an unimport (L<importing>), which with well-behaved pragmas undoes
their effects.

For example, to disable the protection of C<strict> when you need to do
something symbolic:

=begin programlisting

Expand Down Expand Up @@ -137,8 +142,9 @@ X<pragmas; writing>

Perl 5.10.0 added the ability to write your own lexical pragmas in pure Perl
code. C<perldoc perlpragma> explains how to do so, while the explanation of
C<$^H> in C<perldoc perlvar> explains how the feature works. The CPAN has begun
to gather useful pragmas, including:
C<$^H> in C<perldoc perlvar> explains how the feature works.

The CPAN has begun to gather useful pragmas. Some of the most useful are:

X<CPAN; C<autobox>>
X<CPAN; C<perl5i>>
Expand Down
2 changes: 1 addition & 1 deletion sections/style.pod
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ documenting, packaging, testing, and distributing your code.
(U<http://learn.perl.org/faq/beginners.html>), browse PerlMonks
(U<http://perlmonks.org/>), and otherwise immerse yourself in the
communityN<See U<http://www.perl.org/community.html>.>. Read code and try to
write solutions--even if you never post them, this is a great opportunity to
answer questions--even if you never post them, this is a great opportunity to
learn.

=back
Expand Down

0 comments on commit 337f583

Please sign in to comment.