[Pdx-pm] Instance hash ( keyed array )

Austin Schutz tex at off.org
Tue Oct 17 17:08:01 PDT 2006


On Tue, Oct 17, 2006 at 01:32:37PM -0700, Roderick A. Anderson wrote:
> I'm working on a module [0] that needs to do something I have not seen 
> in any other module or documentation.  It may be my ignorance that is 
> making this complicated.
> 
> I need to build a, sometimes, quite large hash table ( 40,000 - 470,000 
> records ) one record at a time.  The method will return the key it is 
> used to the caller so it can be used to key the rest of the data not 
> passed in to the method.
> 
> Here is the sub.
> 
> sub add_addr {
> 
>      my $self = shift;
>      my @stuff = @_;
> 
>      my $recid = $self->inc_recid();
>      my $addr = join( $FldDelim, $recid, @stuff );
>      $addr .= $RcdDelim;
> 
>      $self->{addr_data}->{$recid} = $addr;
> 
>      return $recid;
> }
> 
> Is there a better way to do this?
> 
	There are innumerable "other" ways to do this (as other posts have
demonstrated). Better is somewhat subjective and also depends on your goal.

	Does it work? Is it maintainable? Is it fast enough? Are you embarking
on complex code which solves an already solved problem (i.e. is there an easier
way to do it on CPAN)?

	"maintainable" is usually critical. Having comments helps, following
convention helps. Having tests is very helpful (some would say critical,
especially when creating reusable code).

	Keeping your same logic (if it makes sense to you and works don't
fool with it) here is (more or less) how I would accomplish this, assuming no
other constraints like maximal performance:



package MyModule;

.. skipping init lines and other module docs

# Note the documentation states what it takes, what it does, what it returns,
# and error/exception usage. Note the documentation does _not_ use
# abbreviations. 

=head2 $self->add_addr(@stuff)

	Given @stuff representing an address, format and save in a record.
Returns a record ID. No error conditions are possible.

=cut

sub add_addr {
  my($self, @stuff) = @_;

  # Get a new record id
  my $recid = $self->inc_recid();
  # Format into an addr.
  my $addr = join( $FldDelim, $recid, @stuff );
  $addr .= $RcdDelim;

  # Save the addr in a hash keyed by recid.
  $self->{addr_data}->{$recid} = $addr;

  return $recid;
}
1;


	Here's a test:

t/add_addr.t

use MyModule;
use Test::More qw(no_plan);

MyModule->init();

@stuff=(1,2,3);
my($addr_holder) = MyModule->new();
# (Usually better would be to pass \@stuff, btw).
$recid = $addr_holder->add_addr(@stuff);
ok( $recid );
ok( $self->get_data($recid) = 'some text' );
...

	hth.

	Austin


More information about the Pdx-pm-list mailing list