# 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" );