DEV Community

Discussion on: Daily Challenge #67- Phone Directory

Collapse
 
choroba profile image
E. Choroba • Edited

Object oriented solution in Perl. It also replaces an underscore by a space in the address as shown in the example. Space normalization was needed, too, as after removing the number or the name from the middle of the address, there can be spaces on both sides.

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

{   package Phone::Book;
    sub new {
        my ($class, $file_handle) = @_;
        my %phonebook;
        while (<$file_handle>) {
            s/\+(\d{1,2}-\d{3}-\d{3}-\d{4})// and my $number = $1;
            s/<(.*?)>// and my $name = $1;
            my $address = s/^[^\w.]*|[^\w.]*$//gr;

            # This is not mentioned in the spec but appears in the examples.
            $address =~ s/_| {2,}/ /g;

            if (exists $phonebook{$number}) {
                $phonebook{$number} = {
                    Error => "Too many people: $number"};
            } else {
                $phonebook{$number} = {
                    Phone => $number, Name => $name, Address => $address};
            }
        }
        bless \%phonebook, $class
    }

    sub search {
        my ($self, $number) = @_;
        if (exists $self->{$number}) {
            return $self->{$number}
        } else {
            return {Error => "Not found: $number"}
        }
    }
}

use Test::More tests => 5;

my $pb = 'Phone::Book'->new(*DATA);

is_deeply $pb->search('00-000-000-0000'), {
    Error => 'Not found: 00-000-000-0000'};

is_deeply $pb->search('1-234-567-8901'), {
    Error => 'Too many people: 1-234-567-8901'};

is_deeply $pb->search('1-541-754-3010'), {
    Phone   => '1-541-754-3010',
    Name    => 'J Steeve',
    Address => '156 Alphand St.'};

is_deeply $pb->search('1-541-914-3010'), {
    Phone   => '1-541-914-3010',
    Name    => 'E Kustur',
    Address => '133, Green, Rd. NY-56423'};

is_deeply $pb->search('48-421-674-8974'), {
    Phone   => '48-421-674-8974',
    Name    => 'Anastasia',
    Address => 'Via Quirinal Roma'};

__DATA__
/+1-541-754-3010 156 Alphand_St. <J Steeve>
 133, Green, Rd. <E Kustur> NY-56423 ;+1-541-914-3010!
<Anastasia> +48-421-674-8974 Via Quirinal Roma
<Duplicate 1> +1-234-567-8901 Long Way, Tipperary
<Duplicate 2> 0, Invisible Path +1-234-567-8901