anbutechie has asked for the wisdom of the Perl Monks concerning the following question:
Hi,
Lets say, I m defining and prototyping a subroutine (fun).
sub fun(\$$;$)
{
print "\n";
print shift;
print shift;
print shift;
}
I m calling the subroutine (fun) by passing 2 scalar and a constant value
$a=5; $b=6;
fun($a,$b,3);
My question is, where will be the value of $a, $b and constant value stored, and how can i use them in subroutine?
Regards,
Anbarasu
Re: How can I use the values which is passed as arguments?
by CountZero (Bishop) on Mar 10, 2009 at 07:10 UTC
|
If you are not sure how parameters are passed in and out of a subroutine, you should definitely shy away from prototypes.perldoc perlsub says: The Perl model for function call and return values is simple: all
functions are passed as parameters one single flat list of scalars, and
all functions likewise return to their caller one single flat list of
scalars. Any arrays or hashes in these call and return lists will
collapse, losing their identities--but you may always use
pass-by-reference instead to avoid this. Both call and return lists may
contain as many or as few scalar elements as you'd like.
It is customary to pick up the parameters (which are in the @_ array) as the first instruction inside the sub as follows: sub fun {
my ($first, $second, $third) = @_;
}
or, if you do not know how many parameters will be passed:
sub fun {
my @parameters = @_;
}
You can work directly with the @_ array but as its values are an alias to the paramaters passed in, you could unwillingly be changing the original variables and cause some subtle and difficult to trace bugs.
CountZero A program should be light and agile, its subroutines connected like a string of pearls. The spirit and intent of the program should be retained throughout. There should be neither too little or too much, neither needless loops nor useless variables, neither lack of structure nor overwhelming rigidity." - The Tao of Programming, 4.1 - Geoffrey James
| [reply] [d/l] [select] |
|
Thank you very much for your responce,
Subroutine definition : sub func(\$@$)
Subroutine call is : func($a, @b, Sc)
In this case, how can I get the parameters by the statement
($first, $second, $thrid)=@_
regards,
Anbarasu
| [reply] [d/l] |
|
subroutine prototypes in Perl are much discussed because generally using them is a bad idea. For a recent discussion see subroutine prototypes still bad?.
The bottom line is: don't do that. And a follow up line is: Always use strictures (use strict; use warnings;).
Instead of using prototypes consider:
use strict;
use warnings;
my $str = 'Welcome';
my @array = qw(to the world of);
serious ($str, \@array, 'Perl');
sub serious {
my ($str, $arrayRef, $constStr) = @_;
print join (' ', $str, @$arrayRef, $constStr), ".\n";
}
Prints:
Welcome to the world of Perl.
True laziness is hard work
| [reply] [d/l] [select] |
|
Re: How can I use the values which is passed as arguments?
by lakshmananindia (Chaplain) on Mar 10, 2009 at 08:19 UTC
|
| [reply] |
Re: How can I use the values which is passed as arguments?
by ELISHEVA (Prior) on Mar 10, 2009 at 09:39 UTC
|
You seem to have an answer to your question, but moving forward, there are some things to keep in mind with prototypes, namely that: Perl prototypes are a guide to the compiler, not a list of expected types (as in Java and other languages).
In general you should stay away from them unless
- you have a specific reason for creating syntactic sugar, e.g. you want to define a function that can be called in a manner that looks like map {...} @foo. This is especially true for any prototype element involving \: for example, \@, \%, \&.
- you are defining a function (not a method), you are using and you want to make absolutely sure that N parameters are being passed. Prototypes are ignored for methods. This use of prototypes works best with normal expectations about how Perl function parameters are used if your function expects only scalars and references as parameters and you use a prototype consisting entirely of $ characters. However, as you can see, that has little value for type checking.
All other uses are likely not a good idea. For example, you can use prototypes to force the compiler to fail unless a certain general category of variable is passed. However, to do that, you will have to go against normal ideas of how parameters are used. If you do use prototypes for this purpose, document it very carefully. Even then people are likely to mess things up.
Suppose, for example, you are defining a function (not method) and you have a specific reason for insuring that the parameter being passed is an lvalue (i.e. something to which a value can be assigned, like a variable). If function foo is defined sub foo(\$) then the call foo(1) will fail to compile with the complaint: "Type of arg 1 to main::foo must be scalar (not constant item)". Only calls like foo($x) will be accepted by the compiler.
However, the normal Perl convention is to copy parameters to named variables, so users reading the calling code may not be expecting that foo($x) is actually passing \$a (a reference to $a) and is going to change the value of $x in some way. If you had forgone the prototype and passed foo(\$x) instead, readers seeing the function call would know that something might be happening to the value of $x and would take special care.
Best, beth
| [reply] [d/l] [select] |
Re: How can I use the values which is passed as arguments?
by leslie (Pilgrim) on Mar 10, 2009 at 08:43 UTC
|
| [reply] |
|
|