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>


Reply via email to