SPUG: argument-less shift - explicit/implicit [was: Hashes and subroutines]
Michael R. Wolf
MichaelRWolf at att.net
Thu Jan 8 11:16:18 PST 2009
On Jan 7, 2009, at 8:55 PM, Jack Foy wrote:
> Michael R. Wolf wrote:
>> Jack Foy wrote:
>>> sub runCommand {
>>> my $command = shift;
>>> my $rArgs = shift; # or use @_, but see note 1
>>
>> This seems backwards to my way of thinking (i.e. my way of reading
>> and
>> writing code for my own and other's use):
>> You use @_ *implicitly*, but state that *explicit* code is easier
>> to read.
>
> You're right, I was unclear. I meant, it's more explicit to call our
> hypothetical routine like so:
>
> runCommand ($command, \@commandArgs);
>
> rather than something like this:
>
> runCommand ($command, @commandArgs);
>
> You gave one example of how that might be implemented:
>
>> sub xxx {
>> my ($first_arg, $second_arg, @remaining_args) = @_;
>> }
>
> I avoid that approach because it makes it much more expensive to pass
> around and manipulate large data structures (by requiring a copy of
> every element of @remaining_args).
>
OK. Got it. I agree. SImple arguments should come in as a list, but
complex or large arguments should come in as a reference.
In that case, I typically tack "_ref" to the end of the variable. I
typically do *not* like hungarian notation, but since scalars can be
used for so many things, it's more readable (for my definition of
readable) to differentiate the different kinds of scalars. I guess
what I'd call $action_ref, you call $rAction. Since my fingers grew
up at Bell Labs (writing C), I tend to use underscore more than the
shift key.
I still don't like shift without an argument. It's too contextual for
my taste.
> By the way, note that a further alternative is to use the "magic
> goto":
>
>
> sub runCommand {
> my $command = shift;
>
Thanks for *showing* the magic...
>
> goto &$rAction;
> }
>
>
> This really does behave as though the caller to runCommand() actually
> invoked the selected caller directly! It replaces runCommand() with
> the
> selected routine on the call stack, with @_ as the argument. There
> are
> rare times when this is the Right Thing. Use with appropriate
> caution.
>
... and thanks for warning about its limited usefulness.
Since it's such powerful "magic", I'd be tempted to put in a comment.
Factoring in your suggestions, I'd refactor the code to
sub runCommand {
my $command = shift @_;
my %actions = (
play => \&sub1,
that => \&sub2,
funky => \&sub3,
music => \&sub4,
'white boy' => sub { 'lay down the rhythm and play
that funky music' until 'you die' }
);
my $action_ref = $actions{$command};
# Magic goto...
goto &{$action_ref} if $action_ref;
return LogError ("Unknown command '$command'");
}
Depending on the level of *other* readers, I may or may not augment
the "magic goto" comment.
--
Michael R. Wolf
All mammals learn by playing!
MichaelRWolf at att.net
More information about the spug-list
mailing list