http://qs321.pair.com?node_id=152401


in reply to Re: Re: Beginner's Object Orientation Exercises?
in thread Beginner's Object Orientation Exercises?

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.

use strict; my $light = Flashlight->new(); my %menu = ( 1 => ['Turn On', sub { $light->turn_on }], 2 => ['Turn Off', sub { $light->turn_off }], 3 => ['Toggle', sub { $light->toggle }], 4 => ['Flash', sub { print flash($light),"\n" }], 5 => ['Change Level', sub { change_level($light) }], 6 => ['Status', sub { print $light->to_string }], 7 => ['Exit', sub { exit }], ); while(1) { print menu(); chomp(my $choice = <>); last if $choice =~ /^(exit|q|end|x|quit)/i; next unless exists $menu{$choice}; &{$menu{$choice}->[1]}; } sub menu { my $string; for (sort keys %menu) { $string .= sprintf ("%d) %s\n",$_,$menu{$_}->[0]); } return $string . 'Enter choice:'; } sub flash { my $ref = shift; return $ref->is_on ? "The flashlight is on already." : "A flash of light beams through the air!" } sub change_level { my $ref = shift; print "Enter Level: "; chomp (my $lvl=<>); $ref->level($lvl); print "Power is at ", $ref->level, "\n"; } ############################################### package Flashlight; # constructor sub new { my $class = shift; my $power = shift || 0; my $level = shift || 0; my $self = { level => $level, power => $power, }; return bless $self, $class; } # set method sub turn_on { my $self = shift; $self->{'power'} = 1; } # set method sub turn_off { my $self = shift; $self->{'power'} = 0; } # set method sub toggle { my $self = shift; $self->{'power'} = ! $self->{'power'}; } # get or set method sub level { my $self = shift; my $level = shift; return $self->{'level'} unless $level; $self->{'level'} = $level; } # get method sub is_on { my $self = shift; return $self->{'power'}; } # get method sub to_string { my $self = shift; my $string; while (my($k,$v) = each %$self) { $string .= "$k => " . ($v || 0) . "\n"; } return $string; }

jeffa

L-LL-L--L-LL-L--L-LL-L--
-R--R-RR-R--R-RR-R--R-RR
B--B--B--B--B--B--B--B--
H---H---H---H---H---H---
(the triplet paradiddle with high-hat)