sub list_entries { my ($filename) = @_; ... return { $key => { ...}, $key => {...}, .. ]; } sub add_entry { my ($filename, $key, %data) = @_; ... sub delete_entry { my ($filename, $key) = @_; ... sub update_entry { my ($filename, $key, %data) = @_; .... #### package MyDatabase; sub new { my $class = shift; my $self = {}; bless $self, $class; return $self; }; sub set_schema { my ($self, @fields) = @_; $self->{'fields'} = [@fields]; }; sub set_filename { my ($self, $filename) = @_; $self->{'filename'} = $filename; }; sub read_entries { my ($self) = @_; $self->{'data'} = {}; open(F,"<".$self->{'filename'}) || die "Could not open ".$self->{'filename'}." to read"; while (my $line = ) { my ($key, @field_values) = split(/:/,$line); for (@{$self->{'fields'}}) { $self->{'data'}{$key}{$_} = shift(@field_values); } } close(F); }; sub write_entries { my ($self) = @_; open(F,">".$self->{'filename'}) || die "Could not open ".$self->{'filename'}." for writing"; for my $key (keys %{$self->{'data'}}) { # Prints out the key then the data fields in order. print F join(':',($key, map {$self->{'data'}{$key}{$_}} @{$self->{'fields'}}))."\n"; } close(F); } sub list_entries { my ($self) = @_; $self->read_entries(); return %{$self->{'data'}}; } sub set_entry { my ($self, $key, %data) = @_; eval { $self->read_entries(); }; # drop exceptions for the read on set, if the db doesn't exist, we'll create it. $self->{'data'}{$key} = \%data; $self->write_entries(); } sub delete_entry { my ($self, $key) = @_; $self->read_entries(); delete $self->{'data'}{$key}; $self->write_entries(); } #### my $db = new MyDatabase(); $db->set_filename("test.db"); $db->set_schema("first name","last name","email"); $db->set_entry("testentry",( "first name" => "Phi", "last name" => "RatE", "email" => 'this@is.a.test.com')); my %entries = $db->list_entries(); for (keys %entries) { for my $field (keys %{$entries{$_}}) { print "$field -> ".$entries{$_}{$field}."\n"; } }