I really like
Params::Validate for this sort of thing. You can validate both named and positional parameters, you can make things mandatory or optional, you can check to see if it's the right kind of reference or object, check if an object provides a given interface, etc. You can even provide callback hooks to inspect the parameters yourself if P::V doesn't have a specific check that you need.