http://www.perlmonks.org?node_id=513571

jesuashok has asked for the wisdom of the Perl Monks concerning the following question:

Hi Monks,

I know that In perl we can store any types of References using a single Scalar Variable;

like :-

$scale_ref = \$scalar;

$array_ref = \@array;

$hash_ref = \%hash'

I am devloping Modules which is going act as a Interface between many modules.

The requirement is as follows :-

* I want to make a Scalar Variable which has to hold only Array Reference.

For example :-

sub collect_all_users_from_tables { $table_list = @_; }
In the above example I want to make the $table_list to hold only Array reference.

Because as module developer I may not aware who is going to use my module. But I need to take care those

things in my module.

In othere Languages like C or C++ character pointer contain only character pointer.

I want the similaar things to be done in Perl also.

I know that this can be done in perl

But I am not aware of this. I hope monks will help me.

I need some efficient way of doing this.

This can be done by doing some explicit like

ref(@_) ne ARRAY' { + Carp 'Only Array can be processed'; }
Without explicit check is it possible to bring that future ?

"Keep pouring your ideas"

Replies are listed 'Best First'.
Re: Strict to references of a particular Variable of particular type.
by Zaxo (Archbishop) on Dec 02, 2005 at 13:00 UTC

    use Tie::Constrained; tie my $array_ref, 'Tie::Constrained', sub { ref $_[0] eq 'ARRAY' };
    After that, an attempt to assign anything but an unblessed array ref will fail. Continuing,
    tie my $hash_ref, 'Tie::Constrained', sub { ref $_[0] eq 'HASH' }; tie my $scalar_ref, 'Tie::Constrained', sub { ref $_[0] eq 'SCALAR' }; tie my $scalar_value, 'Tie::Constrained', sub { not ref $_[0] }; tie my $query, 'Tie::Constrained', sub { ref $_[0] and $_[0]->isa('CGI') }, CGI->new;
    There are all kinds of possibilities.

    After Compline,
    Zaxo

Re: Strict to references of a particular Variable of particular type.
by Roger (Parson) on Dec 02, 2005 at 12:59 UTC
    It's always a good practise to check your input parameters inside your subroutine. Even in C/C++ you need to check if a pointer is NULL. This is called defensive programming. A module programmer must always assume that what might go wrong will go wrong. Explicit checking is always necessary to produce robust code.

    Perl supports prototype checking (although many people choose not to use it). For example, sub foo($); tells Perl that the subroutine 'foo' only takes a single scalar as parameter. If you pass other data type into the sub, Perl will complain. Combining prototyping and explcit checking, you can make your module more robust.

    By the way, ref(@_) is not going to do what you think it will do. You would need to do something along the lines of:
    #!/usr/bin/perl -w use strict; use Carp; use Data::Dumper; sub array_ref { my $array_ref = shift; croak 'Not an array reference' unless ref($array_ref) eq 'ARRAY'; print Dumper($array_ref); } my @array = qw/ 1 2 3 4 5 /; my %hash = qw/ 1 1 2 2 3 3 4 4 5 5 /; array_ref(\@array); array_ref(\%hash);
    and the output
    $VAR1 = [ '1', '2', '3', '4', '5' ]; Not an array reference at try.pl line 9 main::array_ref('HASH(0x81d4e14)') called at try.pl line 18

    Update: crossed out the section on Perl prototype checking

      People avoid prototypes for enforcing argument types and argument count because prototypes do not enforce argument types or argument count:

      sub foo ($) { print ">>$_[0]<<\n"; }; my @bar = (4,5,6); foo 1,2,3; foo @bar; foo(@bar);

      I forgot to point to Tom Christiansens Far More Than You Ever Wanted To Know About Prototypes - it details the uses and abuses of prototypes, and my rule of thumb has been to avoid them unless I really need them.

        Thanks for the clarification. The example was very helpful.

Re: Strict to references of a particular Variable of particular type.
by Fletch (Bishop) on Dec 02, 2005 at 14:09 UTC
Re: Strict to references of a particular Variable of particular type.
by mkirank (Chaplain) on Dec 04, 2005 at 20:05 UTC
    If you are dealing with blessed references then it is better to use UNIVERSAL::isa instead of ref