Reminder: Phoenix.pm: Meeting 07/18/2002
Scott Walters
phaedrus at illogics.org
Fri Jul 19 01:05:57 CDT 2002
Thanks everyone who showed up, and as always, Doug for having us.
Errata:
The other thing I was hoping to see a slide on but neglected to have
was interface.pm.
interface.pm is a pragma that does compile-time interface checking.
For example:
use interface 'DBI::DBD', 'Clonable', 'Storable';
...code...
would look through DBI/DBD.pm, Clonable.pm, and Storable.pm, and make sure
that your package contained every method that each of these modules did.
It also lists your module as ->isa() for each thing you list as an interface.
ImplicitThis.pm and interface.pm are both available on CPAN:
http://www.cpan.org/modules/by-authors/id/S/SW/SWALTERS/
With the inner classes example, I screwed up the slide:
The example should have read:
sub getIterator {
my $parentThis = shift;
return eval {
package WebsafeColors::Iterator;
# this mini sub-package only knows how to iterate over our data structure
@ISA=(Iterator);
sub new {
my $type = shift;
my $this = { currentIndex=>0 };
bless $this, $type;
}
sub hasNext {
my $this = shift;
return @{$parentThis->{'colors'}} > $this->{'currentIndex'};
}
sub getNext {
my $this = shift;
die unless $this->hasNext();
return $parentThis->{'colors'}->[$this->{'currentIndex'}++];
}
__PACKAGE__;
}->new();
}
I'm attaching the full test module to this message so that you can run it yourself.
-scott
-------------- next part --------------
#
# this is an example of an inner class in perl.
# an inner class is a class that is wholely contained inside of
# another class. it is declared where it is needed and an instance
# is returned immediately.
#
package Iterator;
# abstract class
sub new { die };
sub hasNext { die };
sub getNext { die };
1;
package WebsafeColors;
sub new {
my $type = shift;
my $this = { };
# this is our internal representation: a large array. we might change this in the future,
# so we dont want to hand out this array directly. instead, we provide an interator
# interface.
my $sixcube = ['00', '33', '66', '99', 'cc', 'ff'];
$this->{'colors'} = [
map { $a = $_; map { $b = $_; map { '0x'.$a.$b.$_ } @$sixcube } @$sixcube } @$sixcube
];
bless $this, $type;
}
sub findClosistColor {
my $this = shift;
my $colorIn = shift;
(my $red, my $green, my $blue) = $this->_intToRGB($colorIn);
my $computeDistance = sub {
return abs($red - $_[0]) + abs($green - $_[1]) + abs($blue - $_[2]);
};
my $it = $this->getIterator(); # we can call this, and so can outsiders
my $minDistance = 1<<25;
my $newColor;
my $colorSafeColor;
my $distance;
while($it->hasNext()) {
$colorSafeColor = $it->getNext();
$distance = $computeDistance->($this->_intToRGB(hex $colorSafeColor));
if($distance < $minDistance) {
$newColor = $colorSafeColor; $minDistance = $distance;
}
}
return $newColor || 0x000000;
}
sub _intToRGB {
my $this = shift;
die unless caller eq __PACKAGE__; # private
my $color = shift;
my $red = ($color & 0xff0000) >> 16;
my $green = ($color & 0x00ff00) >> 8;
my $blue = ($color & 0x0000ff);
return ($red, $green, $blue);
}
sub getIterator {
my $parentThis = shift;
return eval {
package WebsafeColors::Iterator;
# this mini sub-package only knows how to iterate over our data structure
@ISA=(Iterator);
sub new {
my $type = shift;
my $this = { currentIndex=>0 };
bless $this, $type;
}
sub hasNext {
my $this = shift;
return @{$parentThis->{'colors'}} > $this->{'currentIndex'};
}
sub getNext {
my $this = shift;
die unless $this->hasNext();
return $parentThis->{'colors'}->[$this->{'currentIndex'}++];
}
__PACKAGE__;
}->new();
}
1;
More information about the Phoenix-pm
mailing list