Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl Monk, Perl Meditation
 
PerlMonks  

How do you test for return type($,@,%)?

by draco_iii (Acolyte)
on Jun 23, 2000 at 19:53 UTC ( [id://19608]=perlquestion: print w/replies, xml ) Need Help??

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

I have a routine that can return different information depending on what kind of varible is asked of it.
If asking for a $ it returns a single set of data, if you ask for an @ it will return the array. But I can also have it return the information in a hash format. I've thought about passing the varible as a reference thinking that this would be a better way to determine it.

Is this possible?

Originally posted as a Categorized Question.

  • Comment on How do you test for return type($,@,%)?

Replies are listed 'Best First'.
Re: How do you test for return type($,@,%)?
by davorg (Chancellor) on Jun 23, 2000 at 21:46 UTC

    A subroutine can only return a scalar or a list. What the caller does with the result is completely out of the subroutine's control.

    For example:
    sub array { return 0 .. 5; } my %hash = array();

    However, you _could_ do something like the code below, but it's pretty strange stuff and I'm not sure how useful it is :-)

    #!/usr/bin/perl -w use strict; sub get_stuff { my $ref = shift; if (ref $ref) { if (ref $ref eq 'SCALAR') { $$ref = 'This is a scalar'; } elsif (ref $ref eq 'ARRAY') { @$ref = qw(This is an array); } elsif (ref $ref eq 'HASH' ) { %$ref = (1 => 'This', 2 => 'is', 3 => 'a', 4 => 'Hash'); } else { die "Invalid reference type passed to get_stuff.\n"; } } else { die "Non-reference passed to get_stuff.\n"; } } my ($scalar, @array, %hash); get_stuff(\$scalar); get_stuff(\@array); get_stuff(\%hash); print "$scalar\n"; $"='|'; print "@array\n"; print map { $hash{$_} . ' ' } sort keys %hash;
Re: How do you test for return type($,@,%)?
by Russ (Deacon) on Jun 30, 2000 at 04:53 UTC
    A subroutine may only know whether its caller wants a SCALAR or an ARRAY. The wantarray function handles this.
    sub test { if (wantarray){ return 'One String'; } else { return ('A', 'List', 'of', 'Strings'); } }
    There is no built-in way to tell if a subroutine's caller wants a hash, but davorg has posted a sample of how you would do this (see his answer).

    The DBI module uses a similar technique (non-relevant code removed for brevity):

    sub fetchall_arrayref { my $slice= shift || []; my $mode = ref $slice; if ($mode eq 'ARRAY') { push @rows, [ @$row ] while($row = $sth->fetch); } elsif ($mode eq 'HASH') { push @rows, $row while ($row = $sth->fetchrow_hashref); } else { Carp::croak("fetchall_arrayref($mode) invalid") } return \@rows; }
    If you call fetchall_arrayref with an array reference (or no reference), it will return array references. If you call it with a hash reference, it will return hash references.
    $sth->fetchall_arrayref( [] ) # returns Array references $sth->fetchall_arrayref( {} ) # returns Hash references

    Cool stuff!

    Russ

RE: How do you test for return type($,@,%)?
by Shendal (Hermit) on Jun 23, 2000 at 21:35 UTC
    First, a little background info. There are two major contexts we are concerned with here: scalar and list (the others are boolean, void and interpolative -- but that's another topic). There is no hash context. wantarray will tell you if the context is scalar or list, but not if you want a hash.

    That said, you can only tell if you want one value or a list of values. For example:
    $var = mysub(); @var = mysub(); %var = mysub(); sub mysub { print "You want a scalar\n" unless wantarray; print "You either want a hash or an array\n" if wantarray; }
    One quick way I can think of to get around this is by passing references. For example,
    my($var,@var,%var); &mysub(\$var); &mysub(\@var); &mysub(\%var); sub mysub { my($ref) = shift; print "You want a scalar\n" if ref($ref) eq 'SCALAR'; print "You want an array\n" if ref($ref) eq 'ARRAY'; print "You want a hash\n" if ref($ref) eq 'HASH'; }
    Hope that helps,
    Shendal
      I think this is an XYZ question. The interface design question is backwards.

      Instead of asking, "What kind of information does this subroutine return?" he's asking "What kind of information does the caller want?"

      The only place where this question might fit is when you're replacing an existing subroutine, and the interface already takes context into account. (Pointing out wantarray takes care of that.)

      In short, I'm terribly confused by this question altogether, and very curious as to what lead to it.

Re: How do you test for return type($,@,%)?
by bimleshsharma (Beadle) on Nov 16, 2011 at 07:06 UTC

    A subroutine can return only single value. That value could be scalar or reference of variable. If we want to return scalar(single) variable then we can do like..
    return $a;
    If want to return array list or hash list then we need to return reference of array or hash Consecutively like..
    return \@name_of_array_variable;
    return \%name_of_hash_variable;

    Hope this will resolve the issue.

    Originally posted as a Categorized Answer.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://19608]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others making s'mores by the fire in the courtyard of the Monastery: (3)
As of 2024-04-24 23:22 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found