8.3. Adding meaningful code

If we look at the code of the lib/…*.pm file, we'll see that there's practically nothing there. So now it's time that we add some meaningful code to the modules. But first we need to add some tests. Let's add this test script under t/add.t

#!/usr/bin/env perl

use strict;
use warnings;

use Test::More tests => 2;

use MyMath::Ops::Add;

{
    my $adder = MyMath::Ops::Add->new();

    # TEST
    ok ($adder, "Adder was initialised");

    # TEST
    is ($adder->add(2,3), 5, "2+3 == 5");
}

Now we need to add it to the MANIFEST, so it will be included in future versions of Perl. After we did it, let's run ./Build test to see the tests fail:

$ perl Build.PL
Creating new 'MYMETA.yml' with configuration results
Creating new 'Build' script for 'MyMath-Ops' version '0.01'
$ ./Build test
t/00-load.t ....... 1/5 # Testing MyMath::Ops 0.01, Perl 5.012003, /usr/bin/perl5.12.3
t/00-load.t ....... ok
t/add.t ........... Can't locate object method "new" via package "MyMath::Ops::Add" at t/add.t line 11.
\# Looks like your test exited with 255 before it could output anything.
t/add.t ........... Dubious, test returned 255 (wstat 65280, 0xff00)
Failed 2/2 subtests
t/boilerplate.t ... ok
t/pod-coverage.t .. ok
t/pod.t ........... ok

Test Summary Report
-------------------
t/add.t         (Wstat: 65280 Tests: 0 Failed: 0)
  Non-zero exit status: 255
  Parse errors: Bad plan.  You planned 2 tests but ran 0.
Files=5, Tests=22,  1 wallclock secs ( 0.14 usr  0.04 sys +  0.56 cusr  0.11 csys =  0.85 CPU)
Result: FAIL
Failed 1/5 test programs. 0/22 subtests failed.

So now we need to fix the tests. Open lib/MyMath/Ops/Add.pm and write that:

package MyMath::Ops::Add;

use warnings;
use strict;

=head1 NAME

MyMath::Ops::Add - The great new MyMath::Ops::Add!

=head1 VERSION

Version 0.01

=cut

our $VERSION = '0.01';

=head1 SYNOPSIS

Quick summary of what the module does.

Perhaps a little code snippet.

    use MyMath::Ops::Add;

    my $foo = MyMath::Ops::Add->new();
    ...

=head1 EXPORT

A list of functions that can be exported.  You can delete this section
if you don't export anything, such as for a purely object-oriented module.

=head1 FUNCTIONS

=head2 new

Construct a new object.

=cut

sub new
{
    my $class = shift;

    my $self = bless {}, $class;

    $self->_init(@_);

    return $self;
}

sub _init
{
    my $self = shift;

    return;
}

=head2 $self->add($x, $y)

Adds two numbers.

=cut

sub add
{
    my $self = shift;

    my ($x, $y) = @_;
    return $x+$y;
}

=head2 function1

=cut

sub function1 {
}

=head2 function2

=cut

sub function2 {
}

=head1 AUTHOR

Perl Newbie, C<< <perl-newbie at perl-begin.org> >>

=head1 BUGS

Please report any bugs or feature requests to C<bug-mymath::ops at rt.cpan.org>, or through
the web interface at L<http://rt.cpan.org/NoAuth/ReportBug.html?Queue=MyMath::Ops>.  I will be notified, and then you'll
automatically be notified of progress on your bug as I make changes.




=head1 SUPPORT

You can find documentation for this module with the perldoc command.

    perldoc MyMath::Ops::Add


You can also look for information at:

=over 4

=item * RT: CPAN's request tracker

L<http://rt.cpan.org/NoAuth/Bugs.html?Dist=MyMath::Ops>

=item * CPAN Ratings

L<http://cpanratings.perl.org/d/MyMath::Ops>

=item * Search CPAN

L<http://metacpan.org/release/MyMath::Ops/>

=back


=head1 ACKNOWLEDGEMENTS


=head1 COPYRIGHT & LICENSE

Copyright 2009 Perl Newbie.

This program is free software; you can redistribute it and/or modify it
under the terms of either: the GNU General Public License as published
by the Free Software Foundation; or the Artistic License.

See http://dev.perl.org/licenses/ for more information.


=cut

1; # End of MyMath::Ops::Add

And now let's run "./Build test" again:

$ ./Build test
t/00-load.t ....... 1/5 # Testing MyMath::Ops 0.01, Perl 5.014002, /usr/bin/perl5.14.2
t/00-load.t ....... ok
t/add.t ........... ok
t/boilerplate.t ... ok
t/pod-coverage.t .. ok
t/pod.t ........... ok
All tests successful.

Since all tests are successful, we can commit the changes to the repository.

Moving on

Now we can continue to add more tests, and then fix the failing ones. If the code becomes too convoluted, due to modifications, we can refactor it and improve its modularity. Running the existing automated tests after such a change will better make sure that we didn't break something.

This "write more tests", "get tests to pass", "refactor" is the cycle of development and maintenance, and Perl tools such as Module-Build facilitate it.


Written by Shlomi Fish