Beefy Boxes and Bandwidth Generously Provided by pair Networks
Clear questions and runnable code
get the best and fastest answer
 
PerlMonks  

Beginner's Object Orientation Exercises?

by munchie (Monk)
on Mar 17, 2002 at 22:06 UTC ( #152358=perlquestion: print w/ replies, xml ) Need Help??
munchie has asked for the wisdom of the Perl Monks concerning the following question:

I've just finished reading the Perlboot manpage, and I want to practice my newfound knowledge of OOP. Does anyone have any ideas for excercises I could try that use OO?

Keep these points in mind:

  • My perl knowledge is most of Learning Perl (3ed.), and some other stuff I've researched out of curiosity.
  • I've only read the Perlboot manpage, and have no other knowledge of Object Orientation
  • I'm on a Windows machine (running ActivePerl)
Thanks, I hope someone can come up with something!

> munchie, the number munchin newb
Llama: The other other white meat!
(you had to be there :-P)

Comment on Beginner's Object Orientation Exercises?
Re: Beginner's Object Orientation Exercises?
by Juerd (Abbot) on Mar 17, 2002 at 22:30 UTC

    Does anyone have any ideas for excercises I could try that use OO?

    Try creating virtual versions of machines that exist in real. You could create a slot machine (has to know how much the user has won, has to count statistics, has to know how many credits are left, should accept money, should pay out) or the money mechanics in a coffee machine (how much money is there left? how can that be divided into coins?) or a "simple" flashlight (must have on/off, must know whether it's on or off, must know how much battery power is left, must be able to tell how bright the light is at the current power level, and could have a flash button).

    I've only read the Perlboot manpage, and have no other knowledge of Object Orientation

    That's your problem. If your knowlegde is not sufficient, you should learn more - it's the way of life.

    Thanks, I hope someone can come up with something!

    Don't forget that using object oriented modules can help a lot. Try to know _why_ they are object oriented instead of functional, try to figure out how the objects work, and read sources.

    Good luck!!

    U28geW91IGNhbiBhbGwgcm90MTMgY
    W5kIHBhY2soKS4gQnV0IGRvIHlvdS
    ByZWNvZ25pc2UgQmFzZTY0IHdoZW4
    geW91IHNlZSBpdD8gIC0tIEp1ZXJk
    

      I made a Flashlight program.

      #! Perl use vars qw($on $pwrlvl); use strict; my $on = "no"; my $pwrlvl = "3"; my $fl = "Flashlight"; print "You are holding a flashlight. What will you do? \n"; print "(TurnOn, TurnOff, Flash, ChangePowerLevel, ExitProgram)\n"; print "/Status Checks/=\\ pwrlvl, ison \\\n"; while(<STDIN>) { chomp; if (/^Change/) { print "Enter Level: "; chomp (my $lvl=<STDIN>); print $fl->ChangePowerLevel("$lvl"); print "\n"; } elsif (/^(exit|q|end|x|quit)/i) { exit; } else { print $fl->$_ ."\n"; } } { #1 package Flashlight; sub TurnOn { $on = "yes"; return "The light is on."; } sub TurnOff { $on = "no"; return "Light is now off."; } sub Flash { if ($on eq "no") { return "A flash of light beams through the air!"; } else { return "The flashlight is on already."; } } sub ChangePowerLevel { my $class = shift; my $level = shift; $pwrlvl = $level; return "The Power level is set at $pwrlvl"; } sub pwrlvl { return "Power is at $pwrlvl"; } sub ison { return "Is it on? Well, $on"; } }
      It has everything but the battery power, which will be easy to implement in a few minutes when I find time.

      Commands: ison, pwrlvl, ChangePowerLevel, TurnOn, TurnOff, Flash

      > munchie, the number munchin newb
      Llama: The other other white meat!
      (you had to be there :-P)

        Errrr..... there's no OO in your example. There's no object. No blessed reference. You hold state in globals -- yack! Perhaps give a closer read to perlboot, perltoot, perltootc, perlobj,and perlbot. When done properly, the same code should support more than one flashlight -- with no conflicts between them.
        nop
        Hmmmm, nop is right ... that is not really OO. You are using packages alright, but not in an OO manner. First, you need a constructor to create the object:
        package Flashlight; sub new { my $class = shift; my $power = shift || 0; my $level = shift || 0; my $self = { level => $level, power => $power, }; return bless $self, $class; }
        This allows you to set a level and whether it is on or off when you instantiate (create) the object:
        my $light = Flashlight->new(1,4);
        which will create a flashlight that is on(1) with a level of 4.

        Next, you really shouldn't print messages to STDOUT inside an object's method(s). Instead, methods really should generally only get and set values. This means that your methods Flash and ChangePowerLevel really belong in the client that uses your Flashlight object. Also, pwrlvl and ison should return true or false values, and should be renamed to more standard names like change_level and is_on.

        Here is a complete re-write of your good but flawed first attempt (don't fret it, OO is an art form that takes a looong time to 'get'). Like music, this is just my interpretation of the problem at hand.

        I made a Flashlight program.

        A program? I thought you wanted to exercise OO? Object properties are usually stored in the object itself, so that you can create multiple instances. If in your program you find that you need another flash light, you'll have to duplicate your entire package, or at least modify it heavily, to support multiple on/off states.

        I took the liberty of re-writing it, so you can OO the other machines yourself.

        package Flashlight; use Carp; use Time::HiRes qw/usleep/; use strict; sub new { my ($class, %options) = @_; my $self = { }; my @required = qw/color/; my @optional = qw/batteries_included type battery_type/; for (@required) { croak "Required named argument $_ was not defined" if not defined $options{$_}; $self->{$_} = $options{$_}; } for (@optional) { $self->{$_} = $options{$_} if exists $options{$_}; } return bless $self, $class; } sub color { my ($self) = @_; return lc $self->{color}; } sub charge_batteries { my ($self, $type) = @_; carp 'Please read the manual!' if defined $type and $type ne $self->{battery_type}; return $self->{batteries_included} = 1; } sub is_on { my ($self) = @_; return $self->{on}; } sub is_off { my ($self) = @_; return ! $self->{off}; } sub on { my ($self) = @_; return undef if not $self->{batteries_included}; $self->{on} = 1; return return 1; } sub off { my ($self) = @_; return $self->{on} = 0; } sub switch { my ($self) = @_; return undef if $self->is_off and not $self->{batteries_included}; return $self->{on} = ! $self->{on} } sub flash { my ($self, $duration) = @_; croak 'Cannot flash while on' if $self->is_on; croak 'Cannot flash for a negative number of seconds' if $duration + < 0; carp 'flash() should be used to do nothing at all, changing durati +on' if defined $duration and $duration == 0; $duration ||= 0.1; $self->on(); usleep $duration; $self->off(); }

        All those $self's and the new constructor indicate this flashlight is an object, and you can create as many flashlights as you want.

        Now, it's your turn. I can say only one thing: try harder.

        U28geW91IGNhbiBhbGwgcm90MTMgY
        W5kIHBhY2soKS4gQnV0IGRvIHlvdS
        ByZWNvZ25pc2UgQmFzZTY0IHdoZW4
        geW91IHNlZSBpdD8gIC0tIEp1ZXJk
        

Re: Beginner's Object Orientation Exercises?
by Ryszard (Priest) on Mar 17, 2002 at 23:03 UTC
    My 1st inroads into OOP(erl) were pretty much along your path. I then got a hold of theDamian's book and havent stopped. I highly recommend his book especially chpt3.

    My 1st ever OOP project was a logger. Very, very basic, but it worked, and is still pretty cool, altho' as always (when continuing to learn at 100km/h), when you look back on your old code you shudder.

    I would also recommend reading up on OO theory, and making sure you have your jargon down. Its all great to talk of objects, classes, methods and attributes but what does it all mean? If you dont understand the jargon, you'll get very confused, very easily (and quickly).

    Keep in mind that when you program in OOP, something that took 3 or 4 lines before can take substancially more with your new found OO-fu.

    For example, using the above logger example, you open a file, print to the filehandle, and close the file. Three lines, easy, no sweat. If you wanted to do this OO style, then you need some code to set up each various method you may have, a constructor, and some attributes of the logger. this will take you way past the three lines.

    Dont be discouraged, the advantages are many, modular design, reusability to name a couple.

    Welcome to the world of OOP, good luck.

      I have just GOT to second this - that book by Damian is my Bible. I use it every single day. I have been known to sleep with it - dare I say I "know" it in the "Biblical" sense? (I couldn't resist.)

      My first foray into Perl's OO realm was actually just with packages. I wrote a wrapper for another module. Though not OO, it made me familiar with the world of packages - it was of immense value once I dove more deeply into OO.

      For true OO, I took apart someone's CPAN module and started re-writing it - another good experience. After that, I was ready to make my own.

      Good luck!

Re: Beginner's Object Orientation Exercises?
by Stegalex (Chaplain) on Mar 18, 2002 at 14:24 UTC
    Does anyone have any ideas for excercises I could try that use OO?

    How's about trying to solve a business problem? If you are employed as a programmer, there's no shortage of them.

    Also, in addition to reading Damian Conway's book you should familiarize yourself with data structures and references. I like chicken.
Re: Beginner's Object Orientation Exercises?
by buckaduck (Chaplain) on Mar 18, 2002 at 18:29 UTC
    I started out with something most people can relate to: different types of documents. You can create a generic Document class, and then a series of subclasses: Letter, Memo, SummaryReport, DetailedReport, Thesis, Resume, Timesheet, LetterOfComplaint, whatever.

    In my case, I made the code handle a lot of formatting tricks, and produce output in a variety of formats.

    Whatever you choose, I think the key is to make it something you might actually want to use. That's the only way you'll keep using it in the long run.

    buckaduck

Re: Beginner's Object Orientation Exercises?
by Silicon Cactus (Scribe) on Mar 18, 2002 at 20:53 UTC

    Honestly, if you are new to OOP, you might want to start the way I did. It is Very Basic, and does not really use all the functionality (actually only properties), but at least can get you to understand how to build an object from scratch and how to work with the references to it. (BTW thanks all of you who were patient with me a while back when I was asking these same questions)

    We have good ol' web(non)sense here at work, which as probably a few of you know, is blind to external proxies.

    I found a site in Russia that lists proxy ip's and ports that are open for free use. I thought that was nifty, but it was a pain for me to keep checking it. Enter perl!

    I did some research in CPAN and was disappointed to see the lack of win32 ping modules (or i missed them) that provided response time. I decided to do it the Dirty Way.I ended up snarfing the page using an object and its methods from Win32::Internet, parsed it to get what i needed (good regex use too) and built an object with that data to contain ip,port,responsetime, and lost packets.

    I then backtick a win32 ping command and parse for response time and packet loss, adding the data to the object.

    Afterwards, a report is generated and I am good to go.

    It helped me so much to understand what I am doing. And yes, before I get hit with the badstick, it is slow, gawdawful and ugly, but it was a great learning project.

Re: Beginner's Object Orientation Exercises?
by munchie (Monk) on Mar 20, 2002 at 01:14 UTC
    Ok, here's TRY 2. I'm almost 100% percent sure this is real object orientation. It's a package called AlienFarm that can make, teach, and give powers to aliens. (Constructed using the birth method.)

    #! Perl use strict; { package AlienFarm; sub birth { my $self=shift; my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst)=localtime +(time); my $name=shift; $mon+=1; $year+=1900; my $birth = "$mon $mday, $year"; my $alien = bless { NAME => "$name", BIRTH => "$birth", POWERS => [ ], BRAINS => ["pre-school", "1st grade", "2nd grade", "3rd grade", "4th grade", "5th grade", "6th grade", "7th grade", "8th grade", "9th grade", "10th grade", "11th grade", "12th grade", "Harvard Freshman", "Harvard Sophmo +re", "Havard Junior", "Harvard Senior", "Employed", "C +EO"], LEVEL => "-1" }, "AlienFarm"; } sub birthday { my $decide=shift; ref $decide ? $decide->{BIRTH} : "an unknown time"; } sub name { my $decide=shift; ref $decide ? $decide->{NAME} : "an unknown name"; } sub set_power { my $self=shift; my $power=shift; push @{$self->{POWERS}}, $power; } sub get_powers { my $self=shift; my $num=1; foreach my $power ( @{$self->{POWERS}} ) { print "$num) $power\n"; $num++; } print "\n"; } sub teach_lessons { my $self=shift; my $level = $self->{LEVEL}; $level+=1; $self->{LEVEL} = $level; return "Lesson taught. Level: ". $self->{BRAINS}[$self->{LEVEL}] . +"\n"; } sub schooling { my $self = shift; return $self->{BRAINS}[$self->{LEVEL}]; } }

    > munchie, the number munchin newb
    Llama: The other other white meat!
    (you had to be there :-P)

      Here's a slightly modified version of your AlienFarm module... There are some subtle differences... Can you see what they are?
      #!/usr/bin/perl -w package AlienFarm; use strict; sub birth { my $pkg = shift; my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst)=localtime +(time); my $name = shift; $mon++; $year+=1900; my $birth = "$mon $mday, $year"; my $alien = bless { NAME => "$name", BIRTH => "$birth", POWERS => [ ], BRAINS => ["pre-school", "1st grade", "2nd grade", "3rd grade", "4th grade", "5th grade", "6th grade", "7th grade", "8th grade", "9th grade", "10th grade", "11th grade", "12th grade", "Harvard Freshman", "Harvard Sophmo +re", "Havard Junior", "Harvard Senior", "Employed", "C +EO"], LEVEL => "-1" }, $pkg; } sub birthday { my $decide=shift; ref $decide ? $decide->{BIRTH} : "an unknown time"; } sub name { my $decide=shift; ref $decide ? $decide->{NAME} : "an unknown name"; } sub set_power { my $self=shift; my $power=shift; push @{$self->{POWERS}}, $power; } sub get_powers { my $self=shift; my $num=1; foreach my $power ( @{$self->{POWERS}} ) { print "$num => $power\n"; $num++; } print "\n"; } sub teach_lessons { my $self = shift; $self->{LEVEL}++; return "Lesson taught. Level: ". $self->{BRAINS}[$self->{LEVEL}] . +"\n"; } sub schooling { my $self = shift; return $self->{BRAINS}[$self->{LEVEL}]; }

      Also, you can actually combine set_power and get_power into one sub, called power. But that's an exercise left for the reader...

      Theodore Charles III
      Network Administrator
      Los Angeles Senior High
      4650 W. Olympic Blvd.
      Los Angeles, CA 90019
      323-937-3210 ext. 224
      email->secon_kun@hotmail.com
        I think that I could change
        sub set_power { my $self=shift; my $power=shift; push @{$self->{POWERS}}, $power; } sub get_powers { my $self=shift; my $num=1; foreach my $power ( @{$self->{POWERS}} ) { print "$num => $power\n"; $num++; } print "\n"; }
        into something like:
        sub power { my $self=shift; if ($_[0]) { my $power=shift; push @{$self->{POWERS}}, $power; } else { my $self=shift; my $num=1; foreach my $power ( @{$self->{POWERS}} ) { print "$num => $power\n"; $num++; } print "\n"; } }
        It would be called as $obj->power("Power name") to set, and $obj->power() to view.

        > munchie, the number munchin newb
        Llama: The other other white meat!
        (you had to be there :-P)

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://152358]
Approved by root
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others romping around the Monastery: (12)
As of 2014-10-21 18:43 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    For retirement, I am banking on:










    Results (106 votes), past polls