Beefy Boxes and Bandwidth Generously Provided by pair Networks
Welcome to the Monastery
 
PerlMonks  

Re^3: How do I go from procedural to object oriented programming?

by SimonPratt (Friar)
on Apr 22, 2015 at 12:51 UTC ( [id://1124264]=note: print w/replies, xml ) Need Help??


in reply to Re^2: How do I go from procedural to object oriented programming?
in thread How do I go from procedural to object oriented programming?

Uhh, did a quick update to my previous script, to print the movies on individual lines, as per your OP. Notice how most of the work was done inside the classes, adding and extending function and procedure calls as necessary. main really is only having to deal with the what side of the equation, as opposed to the how, which is encapsulated inside the classes.

use 5.16.2; use warnings FATAL => qw( all ); package movie; sub new { my $class = shift; my %params = @_; my $self = bless {}, $class; $self->title($params{title}); $self->start_year($params{start_year}); $self->end_year($params{end_year}); $self->media($params{media}); $self->based_on($params{based_on}); $self->company($params{company}); return $self; } sub title { my $self = shift; my $title = shift; $self->{title} = $title if $title; return $self->{title}; } sub start_year { my $self = shift; my $start_year = shift; $self->{start_year} = $start_year if $start_year; return $self->{start_year} // 'TBD'; } sub end_year { my $self = shift; my $end_year = shift; $self->{end_year} = $end_year if $end_year; return $self->{end_year} // 'TBD'; } sub media { my $self = shift; my $media = shift; $self->{media} = $media if $media; return $self->{media} // 'TBD'; } sub based_on { my $self = shift; my $based_on = shift; $self->{based_on} = $based_on if $based_on; return $self->{based_on} // 'TBD'; } sub company { my $self = shift; my $company = shift; $self->{company} = $company if $company; return $self->{company} // 'TBD'; } sub run_time { my $self = shift; my $result = $self->end_year(); $result = $self->start_year() if $self->media() eq 'film'; return $result; } sub print { my $self = shift; my $output = $self->title()." is a ".$self->start_year()." "; if ($self->media() eq 'tv') { $output .= "television series which "; if ($self->end_year()) { $output .= "completed in ".$self->end_year(); } else { $output .= "is still running."; } } else { $output .= $self->media()." based on ".$self->based_on()." by +".$self->company(); } say $output; } package library; sub new { my $class = shift; my %params = @_; my $self = bless {}, $class; $self->name($params{name}); $self->add_movie($_) for @{$params{movies}}; return $self; } sub name { my $self = shift; my $name = shift; $self->{name} = $name if $name; return $self->{name}; } sub add_movie { my $self = shift; my $movie = shift; $self->{movies}{$movie->title()}{movie} = $movie; $self->{movies}{$movie->title()}{location} = 'in'; } sub get_allmovies { my $self = shift; my @movies = map {$_->{movie}} values $self->{movies}; return @movies; } sub print { my $self = shift; say "I am a library called '".$self->name()."' and contain the fol +lowing movies:"; say "\t".$_->{movie}->title() foreach values %{$self->{movies}}; } package main; use XML::Simple; my @data = <DATA>; my $movies_data = eval { XMLin("@data") }; my $library = library->new(name => "Lucky's"); foreach my $movie (@{$movies_data->{movie}}) { $library->add_movie(movie->new(%$movie)); } $library->print(); say ""; foreach my $movie ($library->get_allmovies()) { $movie->print(); } __DATA__ <movies> <movie> <title>Firefly</title> <start_year>2002</start_year> <end_year>2003</end_year> <media>tv</media> </movie> <movie> <title>Criminal Minds</title> <start_year>2005</start_year> <end_year>tbd</end_year> <media>tv</media> </movie> <movie> <title>The 10th Kingdom</title> <start_year>2000</start_year> <end_year></end_year> <media>miniseries</media> </movie> <movie> <title>Iron Man</title> <start_year>2008</start_year> <end_year></end_year> <media>film</media> <based_on>comics</based_on> <company>Marvel Comics</company> </movie> <movie> <start_year>2007</start_year> <title>Tin Man</title> <media>miniseries</media> <based_on>novel</based_on> <company>L. Frank Baum</company> </movie> <movie> <title>The Avengers (1998)</title> <start_year>1998</start_year> <media>film</media> <based_on>television series</based_on> <company>Thames Television</company> </movie> </movies>

Replies are listed 'Best First'.
Re^4: How do I go from procedural to object oriented programming?
by Lady_Aleena (Priest) on May 05, 2015 at 05:31 UTC

    SimonPratt, I'm sorry I didn't get back to you sooner. I got distracted. If you want to see my actual data, it is here. I don't know what you used at the bottom of the script, however it looks like it is going to gobble up a lot of screen real estate when you consider I have nearly 2,400 movies' data collected, and there are the additional fields qw(format Wikipedia allmovie IMDb TV.com Flixter genre). I shudder to think of the amount of bytes it would take to store them the way you are. I stored 13 movies for the bytes you used for 6, and 42 in the same amount of lines.

    I told you all that so you know I why I put the data in the same module as my subroutines. To keep storage so small, I have to do a fair amount of processing on each field. Even media gets processed. (If media is written like miniseries:5, miniseries is the media, 5 is the amount of parts it has and goes into $movie->{'counts'}{'episode'}. If I can't have the data in the same module as the subroutines, I will not be able to keep my storage sizes down.

    For example, when processing $series and $franchises (2 hash refs processed after $movies), I need start_year and end_year.

    There are a total of 7 hashes created in the actual module. If there were a way to keep them with the objects subroutines, I wouldn't have to drop the idea of using objects. As long as the data is not included, the module becomes useless to me. The actual module is all inclusive of everything which has to do with movies on my site which includes movies, series, franchises, genres, what I own, etc. Everything this module needs to handle is explained here.

    No matter how hysterical I get, my problems are not time sensitive. So, relax, have a cookie, and a very nice day!
    Lady Aleena

      Hi, Lady_Aleena. No worries, I've been away for a while anyway.

      I had a nosey around your git repository when you first posted the link to it. I thought it was a bit strange that you had gone to so much effort in creating a custom data management interface, however if storage space is that much of a concern to you, then I totally get it :)

      __DATA__ effectively tells Perl that everything after that point should be made available through the DATA handle. You get the same effect by having everything below __DATA__ saved in an external file, then manually opening a filehandle called DATA in order to read the content.

      In your particular case, your data management interface should be re-worked to do all of the object building for you. So, instead of creating a bunch of hashes, then calling a set of functions to populate the hashes, you should be able to add your data library and create a new library object which would be populated with movie objects, which are all populated with the data contained in your raw files.

      Once this is working correctly, it doesn't matter how many scripts need access to this data, they can all simply load your data management library and ask it to give them a library of movies to use.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://1124264]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others scrutinizing the Monastery: (5)
As of 2024-04-19 23:20 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found