in reply to Exceptions and Return Codes
That question doesn't belong in the spirit of Perl. If you want others to decide how you should approach things, you should be using Python, or Java. If you program Perl, you should use what you think is right for you.
I can however, tell you what I usually use. I tend to die for unexpected failures - for instance, failure to open a file, or wrong types of arguments. (But note that Dennis Ritchie once said that a failure to open a file was hardly exceptional). For failures that could be expected (for instance, a search in a datastructure that doesn't find anything), I typically return undef or an empty list, but sometimes 0, or if I want to give some information why a failure occured, I return some predefined constant - negative numbers, or strings, depending what is more appropriate. It should, after all, be possible to determine which return values signal failures, and which ones are normal return values. Sometimes I return a 2-element list, one element indicates success/failure, the other the return values or failure reason.
I tend not to use globals for explanations, except $@ and to a lesser extend $!. I never, never use warn to do internal message passing. warn IMO, communicates to the user, not the rest of the program. I may use warn in combination with the other failure flagging techniques.
Carp is just a wrapper around die and warn, and I do not consider that a different technique.