Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Mike Lewis on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Getting parameter values in subroutines

Status
Not open for further replies.

tsdragon

Programmer
Dec 18, 2000
5,133
0
0
US
This isn't a problem, but a request for discussion. What's the real difference between using these techniques to get the values of parameters in a subroutine:
Code:
my($p1,$p2,$p3) = @_;

my $p1 = shift;
my $p2 = shift;
my $p3 = shift;

my $p1 = @_[0];
my $p2 = @_[1];
my $p3 = @_[2];
I've seen all three methods used (and probably at least one other). In my opinion the third method is horrendous, and the second cumbersome (guess which one I use).

Comments?
 
hmmmmm....... a philosophical question????

I don't see it as a 'performance' or 'best use' question. The interpreter is going to turn these into just about the same thing. Unless your arrays are ENORMOUS and the machine running the code is severely overloaded, the differences in run times associated with these types of syntax choices will be negligible. However, the costs of dealing with obfuscated code can be extremely high.

In general,.......
If writing for myself, I tend to be more concise, maybe even slightly obscure. However, if I'm explaining to someone, I tend to be overly verbose to give clarity.

And...., then...., if I am writing code in an environment where other programmers may have to read/tweak/modify my code, I end up somewhere in the middle with a lot of comments telling what I am doing and where I'm going next.

It's kind of nice to have a slightly philosophical question. I'll be interested to see other responses.




keep the rudder amid ship and beware the odd typo
 
Thanks for the comment.

To expand a little furthur, functionally the first and third methods are pretty much equivalent. The use of shift in the second method means that perl will actually remove the elements from the array while doing the assignment, which is probably slightly less efficient, but I'm sure the difference is essentially negligible. The third might also be slightly slower than the first because it acutally has to look up each element, but again, the difference in speed is probably negligible. Mostly it's a matter of style. I likte the first because it's concise, and lists all the parameters in one line, in order. If you've got optional parameters at the end of the list, it also prevents looking up or attempting to shift off non-existent values, since it should convert the @_ array into a list of values, and simply assign undef to the ones in the list for which there is no value.
 
I personally use the second method, mostly due to it's ease of use and prettiness. And really, the first and the second are equally easy to use. the third seems a bit messy. i use it over the first method as it allows me some control in being able to say:[tt]
sub sub
{
my $name = shift or die "no name supplied to sub!\n";
my $arrref = shift or die "no array supplied to sub!\n";
...
}[/tt]

which isn't solid error protection, or even nessecarily proper error messages, but makes it a little bit easier to find errors...
well, those are my two pennies.
s-) "If you think you're too small to make a difference, try spending a night in a closed tent with a mosquito."
 
Using 'my $p1 = shift' is my preferred method, because it allows you to easily pass both scalars and an array to the sub. You pass your scalars first, then the array. In the sub, you'll use shift to pop the scalars out of @_, then you can just straight out assign '@your_array = @_'.
 
If I want to pass a LIST (NOT AN ARRAY) to a subroutine using my preferred method I just do it like this:
Code:
my($p1, @p2) = @_;
[\code]
I still think it's clearer.

Notice that I made a strong comment about LIST vs ARRAY above - you really can't pass an array to a subroutine without using a reference (which you SHOULD be doing it you really want to pass an array). What you're passing is what perl calls a LIST of values, which is technically NOT the same thing as an array, even though you can assign the list to an array variable. You'll confuse people if you talk about passing an array when you really mean a list of values.

You can still do error checking using my preferred method
(the first) as well, and do it (I think) more clearly.
[code]
die "Parameter 1 missing" unless $p1;
die "Parameter 2 missing" unless $p2;
die "Parameter 2 must be an array reference" unless ref($p2) eq "ARRAY";
I like this better because it separates the assignment of the parameters to variables and the error checking. Of course, I also don't normally use "die" because it doesn't work correctly in CGI programs. I usually call a subroutine that displays an HTML page with the error message and then does an exit.
Meddle not in the affairs of dragons,
For you are crunchy, and good with mustard.
 
well then, it seems that in all areas but 'clearness' they are the same, but i'd say that's more a matter of preference in this case. it seems to be a TMTOWTDI that doesn't matter either way, n'est pas? "If you think you're too small to make a difference, try spending a night in a closed tent with a mosquito."
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top