# lib/Animal.pm
package Animal;
sub new {
my $class = shift;
return bless {}, $class;
}
sub is_furry {
my $self = shift;
warn "We don't know if this animal is furry or not!\n";
return undef;
}
sub make_noise {
my ( $self, $noise ) = @_;
print $noise, "\n";
}
1;
# lib/Bear.pm
package Bear;
use base 'Animal';
# We know bears are furry, so override Animal's is_furry method:
sub is_furry {
my $self = shift;
return 1;
}
sub eat_honey {
my $self = shift;
# Make use of Animal's make_noise method:
$self->make_noise( "Yum!" );
}
1;
# example.pl
use Animal;
use Bear;
my $baloo = Bear->new;
if ( $baloo->is_furry ) {
$baloo->eat_honey;
}
####
# AliceUtils.pm
package AliceUtils;
sub safe_filename {
my $string = shift;
$string =~ s{\W}{}g;
$string = "untitled" if !$string;
return $string;
}
1;
# BobUtils.pm
package BobUtils;
use AliceUtils; # Make sure it's loaded!
sub save_data {
my ( $filename, $data ) = @_;
my $safe_filename = AliceUtils::safe_filename( $filename ) . ".txt";
open my $fh, '>', $safe_filename or die;
print $fh $data or die;
close $fh or die;
return $safe_filename;
}
1;
# example.pl
use AliceUtils;
use BobUtils;
BobUtils::save_data( "my file", "Hello world!\n" );
####
# AliceUtils.pm
package AliceUtils;
# Tell Exporter::Shiny which functions to make available to others:
use Exporter::Shiny 'safe_filename';
sub safe_filename {
my $string = shift;
$string =~ s{\W}{}g;
$string = "untitled" if !$string;
return $string;
}
1;
# BobUtils.pm
package BobUtils;
# Tell AliceUtils which functions we want from it:
use AliceUtils 'safe_filename';
# Tell Exporter::Shiny which functions to make available to others:
use Exporter::Shiny 'save_data';
sub save_data {
my ( $filename, $data ) = @_;
my $safe_filename = safe_filename( $filename ) . ".txt";
open my $fh, '>', $safe_filename or die;
print $fh $data or die;
close $fh or die;
return $safe_filename;
}
1;
# example.pl
use AliceUtils;
use BobUtils 'save_data';
save_data( "my file", "Hello world!\n" );