Take the 2-minute tour ×

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.

share|improve this question
add comment

4 Answers

up vote 3 down vote accepted

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.

share|improve this answer
+1, this is also the recommendation from the official Perl 5 wiki. –  daxim Jun 8 '12 at 13:51
add comment

To check whether $a is a ref you can use


To check what type of reference it is you can use

if (ref($a) eq "HASH") { #or ARRAY

share|improve this answer
add comment

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
share|improve this answer
add comment

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;
share|improve this answer
This just governs how they behave when called as operators, when called with () it provides no guarantees –  jozefg Jun 30 '12 at 20:32
add comment

Your Answer


