use warnings; use strict; use feature 'state'; package Library; sub new { bless {}, shift } sub logger { # Just an example; # could be class or instance method / property, # could hand out different logger objects. state $logger = Library::Logger->new; return $logger; } package Library::Logger; sub new { bless {}, shift } sub log { shift; print "[".gmtime." UTC] @_\n" } package Library::Foo; sub new { bless {}, shift } sub foo { Library->logger->log("access via class method works") } package Library::Bar; use parent -norequire, 'Library'; sub bar { shift->logger->log("inheritance works") } package Library::Quz; sub new { my $class = shift; bless {@_}, $class } sub library { shift->{library} } sub quz { shift->library->logger->log("access via property works") } package main; Library::Foo->new->foo; Library::Bar->new->bar; my $lib = Library->new; $lib->logger->log("access via instance method works"); Library::Quz->new(library=>$lib)->quz;