[sf-perl] passing array and hash references

Rich Morin rdm at cfcl.com
Fri Sep 29 14:03:33 PDT 2006


Quinn's Excellent Hack allows us to alias an incoming reference
as either an array or a hash.  However, this begs the question
of whether it can be used to do both at once, as a typeglob can.
For that matter, can a reference be used in two different ways?
So, I wrote a bit more test code. [2]

The executive summary (as I suspected) is that only a typeglob
can be used in two (or more) different ways.  So, if the Perl 4
code is doing this, some Real Surgery (TM) will be required [1]
on both the calling and called code.  And, to ward off David's
expected response, Real Surgery _should_ be done in this case!


My current musings, FWIW, have moved on to the question of how
to mechanically recognize use of typeglob parameters, generate
the aliasing code, etc.

Part of the problem lies in determining whether the reference
needs to be aliased to an array or a hash.  It would be nice
to determine this, based on the uses that the called code makes
of the passed variable, but this may be hard to do in a reliable
fashion.  However, the function call(s) should be fairly simple
(and reliable) to parse.

My suspicion, in any case, is that some human examination and
editing will be required, at least for oddball cases.  However,
given that other manual effort will be needed (e.g., to add "my"
statements), this may not add greatly to the overall workload.

-r


[1] barring another rabbit from Quinn...

[2] here's the code and the output:

===================================================================

% cat pt2a
#!/usr/bin/env perl
#
# pt2a - test parameter passing methods (further)
#
# Written by Rich Morin, rdm at cfcl.com, 2006.09

use warnings;

{
    my (@array, %hash);

    # Testbed:  Assign some values, then call each function
    #           twice (with an arrayref, then with a hashref).

    $foo[42]   =  'a_val';
    $foo{'42'} =  'h_val';

    t_2a(\@foo);  # Pass an arrayref.
    t_2a(\%foo);  # Pass a hashref.
}


# t_2a - bring in a ref, via a typeglob
#
# Given the typeglob *foo, Perl is able to extract and use
# both its array (@foo) and hash (%foo) portions.
#
sub t_2a {

    (*foo) = @_;

    print "\nt_2a:\n";
    print "  array:  ", $foo[42],   "\n";
    print "  hash:   ", $foo{'42'}, "\n";
}


% pt2a

t_2a:
  array:  a_val
  hash:   h_val

t_2a:
  array:  a_val
  hash:   h_val

===================================================================

% cat pt2b
#!/usr/bin/env perl
#
# pt2b - test parameter passing methods (further)
#
# Written by Rich Morin, rdm at cfcl.com, 2006.09

use warnings;

{
    my (@array, %hash);

    # Testbed:  Assign some values, then call each function
    #           twice (with an arrayref, then with a hashref).

    $foo[42]   =  'a_val';
    $foo{'42'} =  'h_val';

    t_2b(\@foo);  # Pass an arrayref.
    t_2b(\%foo);  # Pass a hashref.
}


# t_2b - bring in and use as a reference
#
# The ref approach gets confused when we try this.
#
# sub t_2b {

    my ($foo) = @_;

    print "\nt_2b:\n";
    print "  array:  ", $foo->[42],   "\n";
    print "  hash:   ", $foo->{'42'}, "\n";
}


% pt2b

t_2b:
  array:  a_val
Can't coerce array into hash at pt2b line 34.

===================================================================

% cat pt2c
#!/usr/bin/env perl
#
# pt2c - test parameter passing methods (further)
#
# Written by Rich Morin, rdm at cfcl.com, 2006.09

use warnings;
use Data::Alias;

{
    my (@array, %hash);

    # Testbed:  Assign some values, then call each function
    #           twice (with an arrayref, then with a hashref).

    $foo[42]   =  'a_val';
    $foo{'42'} =  'h_val';

    t_2c(\@foo);  # Pass an arrayref.
    t_2c(\%foo);  # Pass a hashref.
}


# t_2c - bring in a ref, via an alias
#
# The alias approach gets confused when we try this.
#
sub t_2c {

    my ($foo) = @_;

    alias my @foo = @$foo;
    alias my %foo = %$foo;

    print "\nt_2c:\n";
    print "  array:  ", $foo[42],   "\n";
    print "  hash:   ", $foo{'42'}, "\n";
}


% pt2c

Odd number of elements in anonymous hash at pt2c line 35.
Use of uninitialized value in list assignment at pt2c line 35.

t_2c:
  array:  a_val
Use of uninitialized value in print at pt2c line 39.
  hash:
Not an ARRAY reference at pt2c line 34.

===================================================================
-- 
http://www.cfcl.com/rdm            Rich Morin
http://www.cfcl.com/rdm/resume     rdm at cfcl.com
http://www.cfcl.com/rdm/weblog     +1 650-873-7841

Technical editing and writing, programming, and web development


More information about the SanFrancisco-pm mailing list