Module::Runtime is probably what you want to use for this. Here are the relevant parts...
sub _is_string($) {
my($arg) = @_;
return defined($arg) && ref(\$arg) eq "SCALAR";
}
our $module_name_rx = qr/[A-Z_a-z][0-9A-Z_a-z]*(?:::[0-9A-Z_a-z]+)*/;
sub is_module_name($) {
_is_string($_[0]) && $_[0] =~ /\A$module_name_rx\z/o;
}
This is more restrictive than your current check - in particular it excludes all non-ASCII word characters. This is because Unicode file names are handled pretty inconsistently across different file systems and Perl versions.
Note that this is really a module name check; not a package name check. Modules are files on the filesystem; packages are namespaces. Package names are a lot more relaxed than module names; for example, the space character can be used as a package name:
perl -E'*{" ::foo"} = sub {42}; say " "->foo'
use Moops; class Cow :rw { has name => (default => 'Ermintrude') }; say Cow->new->name