Actually, I don't think it's nummy, but that's neither here nor there.
There is good reasoning behind doing my $class = ref $proto || $proto;. Unfortunately, 99% of people who do that have no idea why they're doing it. The smarter ones will realize that it's doing some sort of error-checking and chalk it up to that.
What that's really doing is co-opting your constructor (typically called new()) and using it as a copy function, (typically called copy() or clone()). There is something in C++ (and, I believe, Java) called a copy constructor, which will do that cloning for you.
I personally think that new() should be reserved for creating a new instance and clone() should be reserved for taking an existing instance and returning a copy of it. That is because the two functionalities are vastly different. new() almost never has to deal with recursive data structures, deep vs. shallow copying, and the like.
In addition, EVERY single time I've seen ref $proto || $proto written, there was no provision made for a copy constructor. In fact, that was the last it did with $proto. Doesn't seem like much of a copy constructor to me!
Personally, I prefer the following construction:
That makes it completely obvious that I'm using new() to return a new instance. I'll create a copier if (and only if) I need one.
Don't go borrowing trouble. For programmers, this means Worry only about what you need to implement.
In reply to Mmmm ... cargo cult progamming is nummy!