The $class is derived from the first parameter, whether it's the class name, or an existing object. This lets you do this:

my $fido = Dog->new();

which is very common, and the less likely

my $rover = $fido->new();

Now, why would you want to instantiate an object based on the type of another object? If you want to make $rover a clone of $fido, then Dog should have a clone() method, instead of overloading the meaning of new().

That's all the ref($proto) || $proto does for you. If you don't need that dubious functionality, then write your constructors like this: