Andrew Gaffney wrote:
>
> I'm not exactly a beginner. I've been using Perl for about 8 months. It's just that
> I've
> never written a subroutine where I need to pass array or hash *references*.
Regardless of how long you have been writing in Perl, if you have not yet:
Started using strict and warnings in every script
Taken time to get comfortable with references and their use as argument to function
Then you are still a beginner.
Prototypes are for very well-established functions that have taken on library status.
There
they can help support a more streamlined coding style. Don't use them at this point
in your
learning efforts.
> > : Now, how do I get those values in the subroutine?
> > :
> > : sub my_subroutine([EMAIL PROTECTED]@) {
> > : my ($scalar1, $scalar2, $arrayref1, $arrayref2) = @_;
> > : }
> >
> > That's about it. Though I might suggest a style change.
> >
> > - Use a variable names that describe the data, not it's
> > structure.
> >
> > - Separate words in variables with underscores.
>
> I do in real code. The above is just sample code.
>
> > - Use comments and white space that aids the maintainer.
> >
> > - Don't use prototypes.
> >
> >
> > sub sales_by_quarter {
> > my(
> > $first_quarter_name, # scalar
> > $second_quarter_name, # scalar
> > $first_quarter_data, # array reference
> > $second_quarter_data, # array reference
> > ) = @_;
> > # ...
> > }
> >
> >
> > sub sales_comparison_by_quarter {
> >
> > # These are references to arrays.
> > # Any changes you make *will* affect the original data.
> > # Think of them as read only.
> > my(
> > $Q1_data, # array reference
> > $Q2_data, # array reference
> > ) = @_;
> >
> > # Region names will default if not provided
> > my $Q1_region = shift || 'Region 1';
> > my $Q2_region = shift || 'Region 2';
> >
> > # ...
> > }
> >
> >
> > : Another thing, how do you access an array through a reference?
> > : I know you access a hash through a reference by doing
> > : '$hashref->{hashkey}' instead of just '$hashref{hashkey}', but
> > : I've never done it with arrays (never needed to).
> >
> > The arrow operator (->) is used to dereference references.
> > Read perlref and perl reftut.
> >
> > $second_quarter_data->[ $month ]
> >
> >
> > : One more thing (I promise). Do I need to do anything special to
> > : pass arrays as references to the function, like this:
> > :
> > : my_subroutine $scalar1, $scalar2, [EMAIL PROTECTED], [EMAIL PROTECTED];
> > :
> > : or can I pass them without the '\'? Sorry for all the
> > : questions in one post, but at least they are all related :)
> >
> > Yes, but you have already answered this at the beginning of
> > your message:
> >
> > : I'm trying to write a subroutine that takes two scalars
> > : and two arrays as parameters. I've read that if you try
> > : to do this in a function, both arrays will get combined
> > : within '@_'.
>
> I don't understand how that explains how I can pass the array and hash *references*
> to my
> function. If I use prototypes, this is taken care of for me.
Don't count on that.
> If I don't use prototypes,
Bad distinction. Just put the prototypes on the shelf, please, and stick to learning
Perl.
> do I need the '\' in front of arrays and hashes in the function call?
If the array was declared statically, one way to offer a reference to it is indeed to
offer
the reference directly in the parameter list. You could also assign a reference to a
scalar,
and offer that scalar as an argument.
my @clunky_stay_at_home_array = qw /yada yada sis boom bah/;
do_spectacular_things with([EMAIL PROTECTED]);
my $sleek_array_keycard = [EMAIL PROTECTED];
visit_wondrous_faraway_places( $sleek_array_keycard);
> What about anonymous
> hashes?
Lets not jump to anonymous hashes specifically right now. how about anonymous
structures in
general? I seldom use statically declared arrays or hashes myself, unless they are
scope to a
very short, throwaway lifetime. Anonymous structures are already packed for travel:
my $sleek_array_keycard = [qw /yada yada sis boom bah/];
visit_wondrous_faraway_places( $sleek_array_keycard);
>
>
> my_subroutine $scalar1, $scalar2, {param1 => 'value1', param2 => 'value2'},
> $arrayref;
>
> In the above, wouldn't the hash just get squashed into @_? Wouldn't my @_ end up as
> the
> following within the function?
Nope. The syntax above could also be written:
my $blandly_named_hash_ref = {param1 => 'value1', param2 => 'value2'};
because the braces act as operators returning a reference to the aqnonymous hash, just
as
brackets do for an anonymous array. That reference is a scalar, which cannot be
flattened, as
it is already atomic.
my_subroutine $scalar1, $scalar2, $blandly_named_hash_ref, $arrayref;
OTOH, if you offered a hash, rather than a reference to a hash
my %blandly_named_hash = (param1 => 'value1', param2 => 'value2');
my_subroutine $scalar1, $scalar2, %blandly_named_hash, $arrayref;
or
my_subroutine $scalar1, $scalar2, (param1 => 'value1', param2 => 'value2'), $arrayref;
The hash contents would be flattened in the list.
A reference is a scalar. Scalars are atomic--they do not get flattened passing through
parameter or return list, or being stored within other structures. This is why
refererences
provide the basis for power programming.
Joseph
--
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
<http://learn.perl.org/> <http://learn.perl.org/first-response>