Browse files

Improved line and pagebreaking for chapter 9.

  • Loading branch information...
1 parent 337f583 commit 5e958deda9e7dcd67fcff1b0ffe1a445e7d5d8ef @chromatic committed Dec 7, 2011
View
40 sections/code_generation.pod
@@ -62,15 +62,13 @@ others:
sub get_$methname
{
my \$self = shift;
-
return \$self->{$attrname};
}
sub set_$methname
{
my (\$self, \$value) = \@_;
-
- \$self->{$attrname} = \$value;
+ \$self->{$attrname} = \$value;
}
END_ACCESSOR
}
@@ -79,10 +77,8 @@ others:
Woe to those who forget a backslash! Good luck convincing your syntax
highlighter what's happening! Worse yet, each invocation of string C<eval>
-builds a new data structure representing the entire code. Compiling code isn't
-free, either.
-
-Even with its limitations, this technique is reasonably simple.
+builds a new data structure representing the entire code, and compiling code
+isn't free, either. Yet Even with its limitations, this technique is simple.
=head2 Parametric Closures
@@ -107,7 +103,6 @@ without requiring additional evaluation:
my $setter = sub
{
my ($self, $value) = @_;
-
$self->{$attrname} = $value;
};
@@ -130,11 +125,11 @@ Installing into symbol tables is reasonably easy, if ugly:
=begin programlisting
{
- my ($getter, $setter) = generate_accessors( 'homecourt' );
+ my ($get, $set) = generate_accessors( 'pie' );
no strict 'refs';
- *{ 'get_homecourt' } = $getter;
- *{ 'set_homecourt' } = $setter;
+ *{ 'get_pie' } = $get;
+ *{ 'set_pie' } = $set;
}
=end programlisting
@@ -174,7 +169,7 @@ generate in a single line:
no strict 'refs';
*{ $methname } = sub {
- # subtle bug: strict refs disabled in here too
+ # subtle bug: strict refs disabled here too
};
}
@@ -191,7 +186,8 @@ the contents of a variable, you can assign to the relevant symbol directly:
{
no warnings 'once';
- (*get_homecourt, *set_homecourt) = generate_accessors( 'homecourt' );
+ (*get_pie, *set_pie) =
+ generate_accessors( 'pie' );
}
=end programlisting
@@ -242,7 +238,8 @@ The difference between writing:
{
for my $accessor (qw( age name weight ))
{
- my ($get, $set) = make_accessors( $accessor );
+ my ($get, $set) =
+ make_accessors( $accessor );
no strict 'refs';
*{ 'get_' . $accessor } = $get;
@@ -316,7 +313,9 @@ To create a class:
use Class::MOP;
- my $class = Class::MOP::Class->create( 'Monkey::Wrench' );
+ my $class = Class::MOP::Class->create(
+ 'Monkey::Wrench'
+ );
=end programlisting
@@ -334,8 +333,8 @@ Add attributes and methods to this class when you create it:
(
attributes =>
[
- Class::MOP::Attribute->new( '$material' ),
- Class::MOP::Attribute->new( '$color' ),
+ Class::MOP::Attribute->new('$material'),
+ Class::MOP::Attribute->new('$color'),
]
methods =>
{
@@ -352,8 +351,11 @@ after you've created it:
=begin programlisting
- $class->add_attribute( experience => Class::MOP::Attribute->new( '$xp' ) );
- $class->add_method( bash_zombie => sub { ... } );
+ $class->add_attribute(
+ experience => Class::MOP::Attribute->new('$xp')
+ );
+
+ $class->add_method( bash_zombie => sub { ... } );
=end programlisting
View
4 sections/distributions.pod
@@ -105,8 +105,8 @@ X<cpanm>
=over 4
-=item * C<App::cpanminus> provides almost configuration-free use of the public
-CPAN. It provides the most common 90% of what a CPAN client needs.
+=item * C<App::cpanminus> is a configuration-free CPAN client. It handles the
+most common cases, uses little memory, and works quickly.
X<CPAN; C<App::perlbrew>>
X<perlbrew>
View
117 sections/files.pod
@@ -25,21 +25,6 @@ you C<warn()> goes to C<STDERR>. This separation of output allows you to
redirect useful output and errors to two different places--an output file and
error logs, for example.
-=begin tip The Many Names of C<DATA>
-
-X<C<DATA>>
-X<C<__DATA__>>
-X<C<__END__>>
-
-The special package global C<DATA> filehandle represents the current file. When
-Perl finishes compiling the file, it leaves C<DATA> available and open at the
-end of the compilation unit I<if> the file has a C<__DATA__> or C<__END__>
-section. Any text which occurs after that token is available for reading from
-C<DATA>. This is useful for short, self-contained programs. See C<perldoc
-perldata> for more details.
-
-=end tip
-
X<builtins; C<open>>
Use the C<open> builtin to get a filehandle. To open a file for reading:
@@ -51,23 +36,32 @@ Use the C<open> builtin to get a filehandle. To open a file for reading:
=end programlisting
+=begin tip Remember C<autodie>?
+
+Assume all examples in this section have C<use autodie;> enabled. If you choose
+not to do this, remember to add error checking yourself.
+
+=end tip
+
+
The first operand is a lexical which will contain the resulting filehandle. The
second operand is the I<file mode>, which determines the type of the filehandle
operation. The final operand is the name of the file. If the C<open> fails, the
C<die> clause will throw an exception, with the contents of C<$!> giving the
reason why the open failed.
You may also open files for writing, appending, reading and writing, and more.
+Some of the most important file modes are:
=begin table File Modes
Z<file_modes_table>
=headrow
-=cell Symbols
+=cell B<Symbols>
-=cell Explanation
+=cell B<Explanation>
=bodyrows
@@ -99,28 +93,39 @@ file otherwise.
=end table
-You can even create filehandles which read from or write to plain Perl scalars:
+You can even create filehandles which read from or write to plain Perl scalars, using any existing file mode:
=begin programlisting
- use autodie; # L<autodie>
-
- my $captured_output;
- open my $fh, '>', \$captured_output;
+ open my $read_fh, '<', \$fake_input;
+ open my $write_fh, '>', \$captured_output;
- do_something_awesome( $fh );
+ do_something_awesome( $read_fh, $write_fh );
=end programlisting
-Such filehandles support all of the existing file modes.
-
X<builtins; C<sysopen>>
C<perldoc perlopentut> offers far more details about more exotic uses of
C<open>, including its ability to launch and control other processes, as well
as the use of C<sysopen> for finer-grained control over input and output.
C<perldoc perlfaq5> includes working code for many common IO tasks.
+=begin tip The Many Names of C<DATA>
+
+X<C<DATA>>
+X<C<__DATA__>>
+X<C<__END__>>
+
+The special package global C<DATA> filehandle represents the current file. When
+Perl finishes compiling the file, it leaves C<DATA> open at the end of the
+compilation unit I<if> the file has a C<__DATA__> or C<__END__> section. Any
+text which occurs after that token is available for reading from C<DATA>. This
+is useful for short, self-contained programs. See C<perldoc perldata> for more
+details.
+
+=end tip
+
=head3 Two-argument C<open>
Older code often uses the two-argument form of C<open()>, which jams the file
@@ -153,8 +158,6 @@ C<while()> loop:
=begin programlisting
- use autodie;
-
open my $fh, '<', 'some_file';
while (<$fh>)
@@ -176,8 +179,6 @@ words, this is shorthand for:
=begin programlisting
- use autodie;
-
open my $fh, '<', 'some_file';
while (defined($_ = <$fh>))
@@ -191,8 +192,10 @@ words, this is shorthand for:
=begin tip Why use C<while> and not C<for>?
-C<for> imposes list context on its operand, which reads the entire file before
-processing any of it. This may use a lot of memory for large files.
+C<for> imposes list context on its operand. In the case of C<readline>, Perl
+will read the I<entire> file before processing I<any> of it. C<while> performs
+iteration and reads a line at a time. When memory use is a concern, use
+C<while>.
=end tip
@@ -207,8 +210,6 @@ The cleanest way to read a file line-by-line in Perl 5 is:
=begin programlisting
- use autodie;
-
open my $fh, '<', $filename;
while (my $line = <$fh>)
@@ -237,8 +238,6 @@ Given a filehandle open for output, C<print> or C<say> to it:
=begin programlisting
- use autodie;
-
open my $out_fh, '>', 'output_file.txt';
print $out_fh "Here's a line of text\n";
@@ -340,14 +339,14 @@ filehandle. When set to a non-zero value, Perl will flush the output after
each write to the filehandle. When set to a zero value, Perl will use its
default buffering strategy.
-=begin sidebar
+=begin tip Automatic Flushing
Files default to a fully-buffered strategy. C<STDOUT> when connected to an
-active terminal--and I<not> another program--uses a line-buffered strategy,
-such that Perl will flush C<STDOUT> every time it encounters a newline in the
+active terminal--but I<not> another program--uses a line-buffered strategy,
+where Perl will flush C<STDOUT> every time it encounters a newline in the
output.
-=end sidebar
+=end tip
X<C<autoflush()>>
X<C<IO::File>; C<autoflush()>>
@@ -357,8 +356,6 @@ filehandle:
=begin programlisting
- use autodie;
-
open my $fh, '>', 'pecan.log';
$fh->autoflush( 1 );
@@ -367,17 +364,12 @@ filehandle:
=end programlisting
X<C<IO::File>>
-
-As of Perl 5.14, you can use any method provided by C<IO::File> on a
-filehandle. You do not need to load C<IO::File> explicitly.
-
-=begin sidebar
-
X<C<FileHandle>>
-In Perl 5.12, you must load C<IO::File> yourself. In Perl 5.10 and earlier, you
-must load C<FileHandle> instead.
-=end sidebar
+As of Perl 5.14, you can use any method provided by C<IO::File> on a
+filehandle. You do not need to load C<IO::File> explicitly. In Perl 5.12, you
+must load C<IO::File> yourself. In Perl 5.10 and earlier, you must load
+C<FileHandle> instead.
X<C<IO::File>; C<input_line_number()>>
X<C<IO::File>; C<input_record_separator()>>
@@ -399,8 +391,6 @@ remove files.>. Open a directory handle with the C<opendir> builtin:
=begin programlisting
- use autodie;
-
opendir my $dirh, '/home/monkeytamer/tasks/';
=end programlisting
@@ -429,7 +419,6 @@ Perl 5.12 added a feature where C<readdir> in a C<while> sets C<$_>:
=begin programlisting
use 5.012;
- use autodie;
opendir my $dirh, 'tasks/circus/';
@@ -492,22 +481,15 @@ C<file()> function to create an object representing a file:
use Path::Class;
my $meals = dir( 'tasks', 'cooking' );
- my $file = file( 'tasks', 'health', 'exoskeleton_research.txt' );
+ my $file = file( 'tasks', 'health', 'robots.txt' );
=end programlisting
-You can get File objects from directories:
-
-=begin programlisting
-
- my $lunch = $meals->file( 'veggie_calzone.txt' );
-
-=end programlisting
-
-... and vice versa:
+You can get File objects from directories and vice versa:
=begin programlisting
+ my $lunch = $meals->file( 'veggie_calzone' );
my $robots_dir = $robot_list->dir();
=end programlisting
@@ -517,7 +499,8 @@ You can even open filehandles to directories and files:
=begin programlisting
my $dir_fh = $dir->open();
- my $robots_fh = $robot_list->open( 'r' ) or die "Open failed: $!";
+ my $robots_fh = $robot_list->open( 'r' )
+ or die "Open failed: $!";
=end programlisting
@@ -589,8 +572,6 @@ takes two operands, the old name of the file and the new name:
=begin programlisting
- use autodie;
-
rename 'death_star.txt', 'carbon_sink.txt';
# or if you're stylish:
@@ -612,12 +593,12 @@ remove one or more files. (The C<delete> builtin deletes an element from a
hash, not a file from the filesystem.) These functions and builtins all return
true values on success and set C<$!> on error.
-=begin sidebar
+=begin tip Better than C<File::Spec>
C<Path::Class> provides convenience methods to check certain file attributes as
well as to remove files completely, in a cross-platform fashion.
-=end sidebar
+=end tip
X<builtins; C<chdir>>
X<C<Cwd>>
View
13 sections/handling_warnings.pod
@@ -37,12 +37,12 @@ Given function parameter validation like:
=begin programlisting
- use Carp;
+ use Carp 'carp';
sub only_two_arguments
{
my ($lop, $rop) = @_;
- Carp::carp( 'Too many arguments provided' ) if @_ > 2;
+ carp( 'Too many arguments provided' ) if @_ > 2;
...
}
@@ -205,8 +205,6 @@ module, C<use> the C<warnings::register> pragma:
B<use warnings::register;>
- 1;
-
=end programlisting
This will create a new warnings category named after the package
@@ -227,12 +225,11 @@ C<deprecated> category:
B<sub import>
B<{>
B<warnings::warnif( 'deprecated',>
- B<'empty imports from ' . __PACKAGE__ . ' are now deprecated' )>
- B<unless @_;>
+ B<'empty imports from ' . __PACKAGE__ .>
+ B<' are now deprecated' )>
+ B<unless @_;>
B<}>
- 1;
-
=end programlisting
See C<perldoc perllexwarn> for more details.
View
100 sections/modules.pod
@@ -9,49 +9,28 @@ The CPAN is, at its core, a system for finding and installing modules. A
I<module> is a package contained in its own file and loadable with C<use> or
C<require>. A module must be valid Perl 5 code. It must end with an expression
which evaluates to a true value so that the Perl 5 parser knows it has loaded
-and compiled the module successfully.
-
-There are no other requirements, only strong conventions.
+and compiled the module successfully. There are no other requirements, only
+strong conventions.
X<C<::>; package name separator>
When you load a module, Perl splits the package name on double-colons (C<::>)
-and turns the components of the package name into a file path. Thus:
-
-=begin programlisting
+and turns the components of the package name into a file path. In practice,
+C<use StrangeMonkey;> causes Perl to search for a file named
+F<StrangeMonkey.pm> in every directory in C<@INC>, in order, until it finds one
+or exhausts the list.
- use StrangeMonkey;
-
-=end programlisting
-
-... causes Perl to search for a file named F<StrangeMonkey.pm> in every
-directory in C<@INC>, in order, until it finds one or exhausts the list. As
-well:
-
-=begin programlisting
-
- use StrangeMonkey::Persistence;
-
-=end programlisting
-
-... causes Perl to search for a file named C<Persistence.pm> in every directory
-named F<StrangeMonkey/> present in every directory in C<@INC>, and so on.
-Finally:
-
-=begin programlisting
-
- use StrangeMonkey::UI::Mobile;
-
-=end programlisting
-
-... causes Perl to search for a relative file path of
-F<StrangeMonkey/UI/Mobile.pm> in every directory in C<@INC>.
+Similarly, C<use StrangeMonkey::Persistence;> causes Perl to search for a file
+named C<Persistence.pm> in every directory named F<StrangeMonkey/> present in
+every directory in C<@INC>, and so on. C<use StrangeMonkey::UI::Mobile;> causes
+Perl to search for a relative file path of F<StrangeMonkey/UI/Mobile.pm> in
+every directory in C<@INC>.
The resulting file may or may not contain a package declaration matching its
-filename--there is no technical reason to do so--but maintenance concerns
+filename--there is no such technical I<requirement>--but maintenance concerns
recommend that convention.
-=begin sidebar
+=begin tip C<perldoc> Tricks
X<C<perldoc>; C<-l>>
X<C<perldoc>; C<-m>>
@@ -63,7 +42,7 @@ file. C<perldoc -lm Module::Name> will print the full path to the F<.pm> file
regardless of the existence of any parallel F<.pod> file. C<perldoc -m
Module::Name> will display the contents of the F<.pm> file.
-=end sidebar
+=end tip
=head2 Using and Importing
@@ -80,9 +59,14 @@ C<import()> method, passing any arguments you provided:
=begin programlisting
- use strict; # calls strict->import()
- use CGI ':standard'; # calls CGI->import( ':standard' )
- use feature qw( say switch ) # calls feature->import( qw( say switch ) )
+ use strict;
+ # ... calls strict->import()
+
+ use CGI ':standard';
+ # ... calls CGI->import( ':standard' )
+
+ use feature qw( say switch );
+ # ... calls feature->import( qw( say switch ) )
=end programlisting
@@ -102,16 +86,16 @@ through C<import()>:
=begin programlisting
+ # no symbolic references
+ # variable declaration required
+ # no barewords
use strict;
- # no symbolic references, variable declaration required, no barewords
- ...
-
{
- no strict 'refs';
-
# symbolic references allowed
- # variable declaration still required; barewords prohibited
+ # variable declaration still required
+ # barewords still prohibited
+ no strict 'refs';
}
=end programlisting
@@ -151,7 +135,7 @@ Similarly:
BEGIN
{
require 'Module/Name.pm';
- Module::Name->unimport( qw( list of arguments ) );
+ Module::Name->unimport(qw( list of arguments ));
}
=end programlisting
@@ -162,12 +146,12 @@ You I<may> call C<import()> and C<unimport()> directly, though outside of a
C<BEGIN> block it makes little sense to do so; after compilation has completed,
the effects of C<import()> or C<unimport()> may have little effect.
-=begin sidebar
+=begin tip Missing Methods Never Missed
If C<import()> or C<unimport()> does not exist in the module, Perl will not
give an error message. They are truly optional.
-=end sidebar
+=end tip
X<modules; case-sensitivity>
X<case-sensitivity>
@@ -226,17 +210,6 @@ the three exported functions. You may also export variables:
=end programlisting
-=begin tip Simplified Exporting
-
-X<CPAN; C<Sub::Exporter>>
-
-The CPAN module C<Sub::Exporter> provides a nicer interface to export functions
-without using package globals. It also offers more powerful options. However,
-C<Exporter> can export variables, while C<Sub::Exporter> only exports
-functions.
-
-=end tip
-
Export symbols by default by listing them in C<@EXPORT> instead of
C<@EXPORT_OK>:
@@ -267,6 +240,17 @@ package with their fully-qualified names:
=end programlisting
+=begin tip Simplified Exporting
+
+X<CPAN; C<Sub::Exporter>>
+
+The CPAN module C<Sub::Exporter> provides a nicer interface to export functions
+without using package globals. It also offers more powerful options. However,
+C<Exporter> can export variables, while C<Sub::Exporter> only exports
+functions.
+
+=end tip
+
=head2 Organizing Code with Modules
Perl 5 does not require you to use modules, nor packages, nor namespaces. You
View
7 sections/taint.pod
@@ -45,7 +45,8 @@ its argument is tainted:
=begin programlisting
- die "Oh no!" if Scalar::Util::tainted( $some_suspicious_value );
+ die 'Oh no! Tainted data!'
+ if Scalar::Util::tainted( $suspicious_value );
=end programlisting
@@ -60,8 +61,8 @@ input consists of a US telephone number, you can untaint it with:
=begin programlisting
- die "Number still tainted!"
- unless $tainted_number =~ /(\(/d{3}\) \d{3}-\d{4})/;
+ die 'Number still tainted!'
+ unless $number =~ /(\(/d{3}\) \d{3}-\d{4})/;
my $safe_number = $1;
View
33 sections/testing.pod
@@ -126,7 +126,8 @@ and displays only the most pertinent information:
# Failed test 'the empty string should be false'
# at truth_values.t line 5.
# Looks like you failed 2 tests of 4.
- truth_values.t .. Dubious, test returned 2 (wstat 512, 0x200)
+ truth_values.t .. Dubious, test returned 2
+ (wstat 512, 0x200)
Failed 2/4 subtests
Test Summary Report
@@ -190,8 +191,8 @@ message:
=begin programlisting
- is( 4, 2 + 2, 'addition should hold steady across the universe' );
- is( 'pancake', 100, 'pancakes should have a delicious numeric value' );
+ is( 4, 2 + 2, 'addition should work' );
+ is( 'pancake', 100, 'pancakes are numeric' );
=end programlisting
@@ -200,7 +201,7 @@ As you might expect, the first test passes and the second fails:
=begin screen
t/is_tests.t .. 1/2
- # Failed test 'pancakes should have a delicious numeric value'
+ # Failed test 'pancakes are numeric'
# at t/is_tests.t line 8.
# got: 'pancake'
# expected: '100'
@@ -217,7 +218,8 @@ without explicitly evaluating the array in scalar context:
=begin programlisting
- my @cousins = qw( Rick Kristen Alex Kaycee Eric Corey );
+ my @cousins = qw( Rick Kristen Alex
+ Kaycee Eric Corey );
is( @cousins, 6, 'I should have only six cousins' );
=end programlisting
@@ -244,8 +246,11 @@ function allows you to specify your own comparison operator:
=begin programlisting
- cmp_ok( 100, $cur_balance, '<=', 'I should have at least $100' );
- cmp_ok( $monkey, $ape, '==', 'Simian numifications should agree' );
+ cmp_ok( 100, $cur_balance, '<=',
+ 'I should have at least $100' );
+
+ cmp_ok( $monkey, $ape, '==',
+ 'Simian numifications should agree' );
=end programlisting
@@ -287,7 +292,7 @@ contents are equal:
my $clonenums = Clone::clone( $numbers );
is_deeply( $numbers, $clonenums,
- 'Clone::clone() should produce identical structures' );
+ 'clone() should produce identical items' );
=end programlisting
@@ -372,21 +377,21 @@ exceptions appropriately. You may also encounter C<Test::Exception>.
=item * C<Test::MockObject> and C<Test::MockModule> allow you to test difficult
interfaces by I<mocking> (emulating but producing different results).
-=item * C<Test::WWW::Mechanize> allows you to test live web applications.
-C<Plack::Test> and C<Test::WWW::Mechanize::PSGI> can do so without requiring
-the use of a live web server.
+=item * C<Test::WWW::Mechanize> allows you to test web applications. Both
+C<Plack::Test>, C<Plack::Test::Agent>, and C<Test::WWW::Mechanize::PSGI> can do
+so without requiring the use of a live web server.
=item * C<Test::Database> provides functions to test the use and abuse of
-databases. C<DBICx::TestDatabase> eases the testing of schemas built with
-C<DBIx::Class>.
+databases. C<DBICx::TestDatabase> helps test schemas built with C<DBIx::Class>.
=item * C<Test::Class> offers an alternate mechanism for organizing test
suites. It allows you to create classes in which specific methods group tests.
You can inherit from test classes just as your code classes inherit from each
other. This is an excellent way to reduce duplication in test suites. See the
C<Test::Class> series written by Curtis Poe at
U<http://www.modernperlbooks.com/mt/2009/03/organizing-test-suites-with-testclass.html>.
-C<Test::Routine> offers similar possibilities and uses Moose (L<moose>).
+The newer C<Test::Routine> distribution offers similar possibilities through
+the use of Moose (L<moose>).
=item * C<Test::Differences> tests strings and data structures for equality and
displays any differences in its diagnostics. C<Test::LongString> adds similar
View
37 sections/universal.pod
@@ -6,7 +6,7 @@ X<C<UNIVERSAL>>
Perl 5's builtin C<UNIVERSAL> package is the ancestor of all other packages--in
the object-oriented sense (L<moose>). C<UNIVERSAL> provides a few methods for
-its children.
+its children to inherit or override.
=head2 The isa() Method
@@ -49,7 +49,8 @@ X<CPAN; C<Test::MockModule>>
Any class may override C<isa()>. This can be useful when working with mock
objects (see C<Test::MockObject> and C<Test::MockModule> on the CPAN) or with
-code that does not use roles (L<roles>).
+code that does not use roles (L<roles>). Be aware that any class which I<does>
+override C<isa()> generally has a good reason for doing so.
=head2 The can() Method
@@ -60,14 +61,26 @@ The C<can()> method takes a string containing the name of a method. It returns
a reference to the function which implements that method, if it exists.
Otherwise, it returns a false value. You may call this on a class, an object,
or the name of a package. In the latter case, it returns a reference to a
-function, not a method.
+function, not a methodN<... not that you can tell the difference, given only a
+reference.>.
+
+=begin tip Does a Class Exist?
+
+While both C<UNIVERSAL::isa()> and C<UNIVERSAL::can()> are methods
+(L<method_sub_equivalence>), you may I<safely> use the latter as a function
+solely to determine whether a class exists in Perl 5. If C<UNIVERSAL::can(
+$classname, 'can' )> returns a true value, someone somewhere has defined a
+class of the name C<$classname>. That class may not be usable, but it does
+exist.
+
+=end tip
Given a class named C<SpiderMonkey> with a method named C<screech>, get a
reference to the method with:
=begin programlisting
- if (my $meth = SpiderMonkey->can( 'screech' )) { ... }
+ if (my $meth = SpiderMonkey->can( 'screech' )) {...}
if (my $meth = $sm->can( 'screech' )
{
@@ -88,7 +101,8 @@ X<CPAN; C<Class::Load>>
use Class::Load;
- die "Couldn't load $module!" unless load_class( $module );
+ die "Couldn't load $module!"
+ unless load_class( $module );
if (my $register = $module->can( 'register' )
{
@@ -108,15 +122,6 @@ The CPAN module C<Module::Pluggable> is a great way to manage plugins.
Override C<can()> in your own code if you use C<AUTOLOAD()>
(L<autoload_drawbacks>).
-=begin sidebar
-
-While both C<UNIVERSAL::isa()> and C<UNIVERSAL::can()> are methods, you may use
-the latter as a function in I<one> known case: to determine whether a class
-exists in Perl 5. If C<UNIVERSAL::can( $classname, 'can' )> returns a true
-value, someone somewhere has defined a class of the name C<$classname>.
-
-=end sidebar
-
=head2 The VERSION() Method
X<C<UNIVERSAL::VERSION>>
@@ -135,7 +140,7 @@ Given a C<HowlerMonkey> module of version C<1.23>:
say $hm->VERSION(); # prints 1.23
say $hm->VERSION( 0.0 ); # prints 1.23
say $hm->VERSION( 1.23 ); # prints 1.23
- say $hm->VERSION( 2.0 ); # throws exception
+ say $hm->VERSION( 2.0 ); # exception!
=end programlisting
@@ -182,7 +187,7 @@ With that said, occasional abuse of C<UNIVERSAL> for I<debugging> purposes and
to fix improper default behavior may be excusable. For example, Joshua ben
Jore's C<UNIVERSAL::ref> distribution makes the nearly-useless C<ref()>
operator usable. The C<UNIVERSAL::can> and C<UNIVERSAL::isa> distributions can
-help you debug anti-polymorphism bugs (L<method_sub_equivalence>), while
+help you debug anti-polymorphism bugs (L<method_sub_equivalence>).
C<Perl::Critic> can detect those and other problems.
Outside of very carefully controlled code and very specific, very pragmatic

0 comments on commit 5e958de

Please sign in to comment.