http://www.perlmonks.org?node_id=11103897


in reply to Newbie question under time constraint

Hi, welcome to Perl, the One True Religion.

Couple of etiquette notes: Asking for people to help you urgently because you are under a deadline usually has the opposite effect. Offering to pay for code here will usually get you sent to https://jobs.perl.org. But, effort is encouraged and you've shown plenty, good job getting as far as you have.

Couple of general programming / asking for technical help notes:

Regarding your program my advice is to use one of the many object frameworks Perl already has. Not only because the features that a good framework has that you are replicating by hand, are stable, tested, efficient, but also because a good OOP framework will allow you to expand your app into new levels of complexity as it grows while hiding the majority of the dirty work. Personally I never write anything OOP without Moo.

Here's something like what you described. (Note only one file.)

$ cat 11103867.pl
package Employee { use Moo; # loads strict and warnings and provides new() has name => (is => 'ro'); has [qw/wage hours/] => (is => 'rw'); }; package Employees { use Employee; use Moo; use namespace::clean; has _db => ( # code can be swapped later when there is a real DB is => 'rwp', default => sub { +{} }, ); sub add { my $self = shift; my $args = shift; # argument validation needed here $self->_db->{ $args->{name} } = $args; } sub find { my $self = shift; my $name = shift; # argument validation needed here my $record = $self->_db->{ $name } or die "$name not found"; return Employee->new( name => $name, wage => $record->{wage}, hours => $record->{hours}, ); } sub avg_hourly_wage { my $self = shift; my ($total_hours, $total_wages); for my $name (keys %{ $self->_db }) { $total_hours += $self->_db->{ $name }{hours}; $total_wages += $self->_db->{ $name }{wage} * $self->_db-> +{ $name }{hours}; } return sprintf('%d.2', $total_wages / $total_hours); } sub pay_change_for { my $self = shift; my $employee = shift; my $new_wage = shift; $employee->wage($new_wage); $self->_db->{ $employee->name }->{wage} = $new_wage; } }; #------------------------------------# use strict; use warnings; use feature 'say'; use Employee; use Employees; my $employees = Employees->new; for my $line (<DATA>) { chomp $line; my ($name, $wage, $hours) = split /,/, $line; $employees->add({ name => $name, wage => $wage, hours => $hours, }); } say 'Query for an employee: '; chomp( my $name = <STDIN> ); my $employee = $employees->find($name); say sprintf('%s earns %s for %s hours', map { $employee->$_ } qw/name +wage hours/); say 'The average hourly wage overall is ' . $employees->avg_hourly_wag +e; say "Give $name a raise? Enter new wage or 'No'"; chomp( my $answer = <STDIN> ); if ($answer =~ /^\d+$/) { $employees->pay_change_for($employee, $answer); } else { say 'No change'; } say 'The average hourly wage overall is now ' . $employees->avg_hourly +_wage; __DATA__ Fred Flinstone,10,40 Barney Rubble,8,40 Dino Flintstone,15,40 Bam-Bam Rubble,5,12 Mr. Slate,65,32

Output:

$ perl 11103867.pl
Query for an employee: Barney Rubble Barney Rubble earns 8 for 40 hours The average hourly wage overall is 21.2 Give Barney Rubble a raise? Enter new wage or 'No' 20 The average hourly wage overall is now 24.2

Hope this helps!

Update: added some more methods for fun


The way forward always starts with a minimal test.