spacer

Webref WebRef   Sitemap · Experts · Tools · Services · Newsletters · About i.com

home / programming / awperl2 / 1 To page 1To page 2To page 3current pageTo page 5
[previous] [next]

Senior Lotus Notes Developer
AMS Staffing Solutions
US-MD-Baltimore

Justtechjobs.com Post A Job | Post A Resume
Developer News
Google Chrome Playing Catch-Up on Extensions
Open Solutions Alliance Gets New Leadership
Red Hat Spacewalk Expands Linux Management

Perl Medic: Transforming Legacy Code. Chapter 3. Pt. 2

Finally we are back in the anodyne land of complete test success. Time to add more tests:

throws_ok { $array[6] = "dog" } qr/out of range/,
     "Bounds exception";
is_deeply(\@array, [ 42 ], "Array contents correct");

These work immediately. But an ugly truth emerges when we try another simple array operation:

lives_ok { push @array, 17 } "Push works";

This results in:

not ok 5 - Push works
#      Failed test (t/03use.t at line 19)
# died: Can't locate object method "PUSH" via package
"Tie::Array::Bounded" (perhaps you forgot to load
"Tie::Array::Bounded"?) at t/03use.t line 19. # Looks
like you failed 1 tests of 5.

Inspecting perltie reveals that PUSH is one of several methods it looks like we’re going to have to write. Do we really have to write them all? Can’t we be lazier than that?

Yes, we can.8 The Tie::Array core module defines PUSH and friends in terms of a handful of methods we have to write: FETCH, STORE, FETCHSIZE, and STORESIZE. The only one we haven’t done yet is STORESIZE:

sub STORESIZE
{
  my ($self, $size) = @_;
  $self->_bound_check($size-1);
  $#{$self->{array}} = $size - 1;
}

We need to add near the top of Bounded.pm:

8. Remember, if you find yourself doing something too rote or boring, look for a way to get the computer to make it easier for you. Top of the list of those ways would be finding code someone else already wrote to solve the problem.

use base qw(Tie::Array);

to inherit all that array method goodness.

This is a big step to take, and if we didn’t have canned tests, we might won¬der what sort of unknown havoc could be wrought upon our module by a new base class if we misused it. However, our test suite allows us to determine that, in fact, nothing has broken.

Now we can add to 01load.t the methods FETCH, STORE, FETCHSIZE, and STORESIZE in the can_ok test:

Example 3.3 Final Version of 01load.t

#!/usr/bin/perl
use strict;
use warnings;

use Test::More tests => 2;
use blib;
BEGIN { use_ok("Tie::Array::Bounded") }

can_ok("Tie::Array::Bounded", qw(TIEARRAY STORE FETCH STORESIZE
         FETCHSIZE));

Because our tests pass, let’s add as many more as we can to test all the boundary conditions we can think of, leaving us with a final 03use.t file of:

Example 3.4 Final Version of 03use.t

#!/usr/bin/perl
use strict;
use warnings;

use Test::More tests => 15;
use Test::Exception; use
blib;
use Tie::Array::Bounded;


my $RANGE_EXCEP = qr/out of range/;

my @array;
tie @array, "Tie::Array::Bounded", upper => 5;
lives_ok { $array[0] = 42 } "Store works";
is($array[0], 42, "Fetch works");

throws_ok { $array[6] = "dog" } $RANGE_EXCEP,
      "Bounds exception";
is_deeply(\@array, [ 42 ], "Array contents correct");

lives_ok { push @array, 17 } "Push works";
is($array[1], 17, "Second array element correct");

lives_ok { push @array, 2, 3 } "Push multiple elements works";
is_deeply(\@array, [ 42, 17, 2, 3 ], "Array contents correct");

lives_ok { splice(@array, 4, 0, qw(apple banana)) }
       "Splice works";
is_deeply(\@array, [ 42, 17, 2, 3, 'apple', 'banana' ],
       "Array contents correct");

throws_ok { push @array, "excessive" } $RANGE_EXCEP,
     "Push bounds exception"; is(scalar @array, 6,
     "Size of array correct");

tie @array, "Tie::Array::Bounded", lower => 3, upper

throws_ok { $array[1] = "too small" } $RANGE_EXCEP,
        "Lower bound check failure";

lives_ok { @array[3..6] = 3..6 } "Slice assignment
     works"; throws_ok { push @array, "too big" }
     $RANGE_EXCEP, "Push bounds exception";

Tests are real programs, too. Because we test for the same exception repeatedly, we put its recognition pattern in a variable to be lazy.

Bounded.pm, although not exactly a model of efficiency (our internal array contains unnecessary space allocated to the first $lower elements that will never be used), is now due for documenting, and h2xs filled out some POD stubs already. We’ll flesh it out to the final version you can see in the Appendix. I’ll go into documentation more in Chapter 10.

Now we create 04pod.t to test that the POD is formatted correctly:

Example 3.5 Final Version of 04pod.t

#!/usr/bin/perl
use strict;
use warnings;

use Test::Pod tests => 1;
use blib;
use Tie::Array::Bounded;
pod_ok($INC{"Tie/Array/Bounded.pm"});

There’s just a little trick there to allow us to run this test from any directory, since all the others can be run with the current working directory set to either the parent directory or the t directory. We load the module itself and then get Perl to tell us where it found the file by looking it up in the %INC hash, which tracks such things (see its entry in perlvar).

With a final “make test”, we’re done:

Files=4, Tests=24, 2 wallclock secs ( 1.58 cusr + 0.24 csys = 1.82 CPU)

We have a whole 24 tests at our fingertips ready to be repeated any time we want.

You can get more help on how to use these modules from the module Test::Tutorial, which despite the module appellation contains no code, only documentation.

With only a bit more work, this module could have been submitted to CPAN. See [TREGAR02] for full instructions.


home / programming / awperl2 / 1 To page 1To page 2To page 3current pageTo page 5
[previous] [next]

internet.comearthweb.comDevx.commediabistro.comGraphics.com

Search:

Jupitermedia Corporation has two divisions: Jupiterimages and JupiterOnlineMedia

Jupitermedia Corporate Info

Legal Notices, Licensing, Reprints, Permissions, Privacy Policy.
Advertise | Newsletters | Tech Jobs | Shopping | E-mail Offers

webref The latest from WebReference.com Browse >
Popular JavaScript Framework Libraries: An Overview - Part 3 · Accessing Your MySQL Database from the Web with PHP · Working with the DOM Stylesheets Collection
Sitemap · Experts · Tools · Services · Email a Colleague · Contact FREE Newsletters 
 The latest from internet.com
MS Access and MySQL · Cisco AutoQoS: VoIP QoS for Mere Mortals · While VoIP Adoption Explodes in Enterprise, Carrier Spending Lags

Created: March 27, 2003
Revised: March 24, 2004

URL: http://webreference.com/programming/awperl2/1