in reply to coding a subroutine as both method and regular function

I disagree that it's "almost always a bad idea". You just have to be careful how you do it.

{ package Foo; use Scalar::Util 'blessed'; sub _process_calling_convention { # discard pkg name, if called as class method: @_ && !ref($_[0]) && $_[0] eq __PACKAGE__ and shift; # return object, if called as object method: @_ && (blessed($_[0])||'') eq __PACKAGE__ ? shift : () } sub bar { my $obj = &_process_calling_convention; if ( defined $obj ) { print "called as object method $obj->( @_ )\n"; } else { print "called as function ( @_ )\n"; } } } # main: test: my $x = bless {}, 'Foo'; print "\nplain module function call:\n"; Foo::bar(); Foo::bar("arg"); print "\nclass method call:\n"; Foo->bar(); Foo->bar("arg"); print "\nobject method call:\n"; $x->bar(); $x->bar("arg");

In this, I've coded based on the presumption that, in the class method call case, you don't care about the class name; it is discarded.

I should also say that I don't know how well this will hold up under inheritance. You'd probably have to tweak certain things, i.e. rather than string test against __PACKAGE__, test using isa or can.

A word spoken in Mind will reach its own level, in the objective world, by its own weight