The construct %Package::
gives access to a package's stash, i.e. the symbol table hash.
All this code is doing is checking whether a given package has been loaded (in which case its stash will exist) and that there is a new
method for the package. If not then require
is used to load the module.
The call to UNIVERSAL::can('package', 'method')
is normally written as 'package'->can('method')
and you can change that here if you like, but the code will work as it stands.
I suggest you do just as the warnings say, and omit the defined
. It would also be nicer if you put the package name in its own variable instead of using the interpolated double-quoted string twice, and you can use the conventional call to can
as I have described. It would look like this
my $package = "${protocol_class}::Client";
unless ( %{"${package}::"} and $package->can('new') ) {
# load missing module
}