My feelings on this subject are that you need to consider what type of parameter(s) are going to be passed to a given sub that you are writing.
- Will you be passing in a pre-existing object? If so, this is an object method, and write it as such.
- Will you be passing in a class name instead? If so, make it a class method.
- Otherwise, if it is a straight utility function which does not take either a class or an object as a mandatory parameter, it is a standalone function. Make it optionally exportable.
Sometimes there is synergy between cases 1 and 2 here, and so the construct
my $pkg = ref($self) || $self;
does the trick.
Having a heteromorphic sub that does the third case as well is hard to achieve and not worth it. But, this is what CGI.pm does - see this node.