So I am a beginning Perl programmer. I have been using it for about a month, however only in the last week or so have I been using it for anything other than sysadmin type tasks. In doing so I ran into the following question,
Perl subprocesses are really flexible, and they don't impose many/any constraints on arguments you pass in. How is it possible to either enforce the number of arguments and/or check whether they're references, scalars etc etc?
To clarify, here's what I currently do for Perl subprocesses:
sub mySub{
($a, $b) = @_;
continue and use these methods
}
But this provides no guarantees about what $a
and $b
hold. Is there anyway to make sure they contain values, say a reference for $a
and a scalar for $b
?
Thanks in Advance.
EDIT: When I said scalar for $b
I mean containing an integer, and not being a reference to some other datastructure.
You can use the Params::Validate module, it provides wide possibilities of checking the argument list.
In your case, something like
validate_pos(@_, { type => HASHREF | ARRAYREF }, { type => SCALAR })
would do it (note that it doesn't have a single type for "ref"). It dies when the parameters don't match.
You should be able to specify this using subroutine prototypes:
See http://perldoc.perl.org/perlsub.html#Prototypes for a full explanation.
sub taking a single scalar
sub foo($) {
my $scalar = shift;
}
sub taking two scalars
sub bar($$) {
my ($scalar1, $scalar2) = @_;
}
sub taking an array
sub baz (+*) {
my $arrayref = shift;
}
sub taking a hash
sub quux (+%) {
my $hashref = shift;
}
To check whether $a is a ref you can use
if(ref($a))
To check what type of reference it is you can use
if (ref($a) eq "HASH") { #or ARRAY
You can perform tests on the arguments to see what they contain. However, there is no point in checking whether a scalar is a scalar.
sub mySub{
my ($a, $b) = @_;
if (ref $a eq 'ARRAY') { ... } # check for array ref
continue and use these methods
}
A variable such as $b
is already a scalar, and can only contain scalar values. A reference, for example, is a scalar value. So you will need to be more specific about what you want the variable to contain.
Counting the arguments is as simple as counting any array:
sub foo {
my $n_args = @_; # array is scalar context returns its size
if (@_ < 4) { # same thing
...
}
In order to validate for example an alphanumeric string, you can do
if ($arg =~ /^[\w\s]+$/) { # contains only whitespace and alphanumerics