Your code is indeed very close to Object Oriented. I translated part of it to
#!/usr/bin/perl
use strict;
use warnings;
my %movies_data = (
'Firefly' => {
'start year' => 2002,
'end year' => 2003,
'media' => 'tv',
},
'Criminal Minds' => {
'start year' => 2005,
'end year' => 'tbd',
'media' => 'tv',
},
'The 10th Kingdom' => {
'start year' => 2000,
'media' => 'miniseries',
},
'Iron Man' => {
'start year' => 2008,
'media' => 'film',
'based on' => 'comics',
'company' => 'Marvel Comics',
},
'Tin Man' => {
'start year' => 2007,
'media' => 'miniseries',
'based on' => 'novel',
'company' => 'L. Frank Baum'
},
'The Avengers (1998)' => {
'start year' => 1998,
'media' => 'film',
'based on' => 'television
+ series',
'company' => 'Thames Tele
+vision',
},
);
{ package Movie;
use Moo;
use Time::Piece;
my $current_year = localtime->year;
has 'title' => ( is => 'ro',
required => 1 );
has 'media' => ( is => 'ro',
required => 1,
isa => sub {
shift =~ /^(?:tv|miniseries|film)$/ or d
+ie
} );
has 'start_year' => ( is => 'ro',
required => 1,
isa => sub { shift > 1870 or die } );
has 'end_year' => ( is => 'ro',
default => $current_year );
has 'based_on' => ( is => 'ro',
isa => sub {
shift =~ /^(?:comics|novel|television se
+ries)$/
or die
});
has 'company' => ( is => 'ro' );
around media => sub {
my ($orig, $self) = @_;
my $media = $self->$orig;
return 'tv' eq $media ? 'television series' : $media
};
sub movie_is {
my $self = shift;
my $movie_is = join ' ', $self->title, 'is a',
grep defined, $self->start_year,
$self->media,
$self->basis,
$self->run_time;
return "$movie_is."
}
sub basis {
my $self = shift;
my $basis = $self->based_on
? ('based on the ' . $self->based_on . ' by ' . $self->compa
+ny)
: undef;
return $basis
}
sub run_time {
my $self = shift;
my $run_text;
if ('television series' eq $self->media) {
if ($self->end_year eq 'tbd') {
$run_text = 'which is still running';
} elsif ((my $run_time = $self->end_year - $self->start_ye
+ar) > 0) {
$run_text = "which ran for $run_time year"
. ($run_time > 1 ? 's' : q());
}
}
return $run_text
}
}
for my $title (sort keys %movies_data) {
my $movie = 'Movie'->new( title => $title,
map { (my $t = $_) =~ s/ /_/;
$t => $movies_data{$title}{$_} }
keys %{ $movies_data{$title} });
print $movie->movie_is, "\n";
}
I don't like the result much, though. When writing OOP code, you should concentrate on methods (what the objects do), not on the attributes (what properties the objects have). I haven't studied the full code to find out more than shown here, but e.g. the run_time method seems ugly.