[Date Prev][Date Next][Thread Prev][Thread Next] [Search] [Date Index] [Thread Index]

Re: [MacPerl-WebCGI] Pushing Array Refs Revisited (with solution)



At 2:22 AM -0400 8/7/99, Randy M. Zeitman wrote:
>Is this a bug or am I missing something? (very hopefully the latter...)
>
>Given:
>@a = (1,2,3);
>@b = (4,5,6);
>push @refs, [@a];
>push @refs, [@b];
>
>The statement
>print "$#$refs\n"; results in -1 (huh?)
>print "$#refs\n"; results in 1 (correct...no $ reference in the array ref...)
>
>

1. References are always scalars; that is, variables for storing 
references are of the type "$whatever", not @whatever, %whatever, 
etc. So when your script says:

	push @refs, [@a];
	push @refs, [@b];

it's pushing references to @a and @b into the array @refs. If you 
print @refs, you'll get something like:

	print "@refs";

output:	ARRAY(0x7565350) ARRAY(0x7565380)   # your array values will vary

2. So far nothing's been DE-referenced. If you wanted to get the 
values of @a and @b, you'll have to dereference the _elements_ of 
@refs, not @refs itself.

	print "@{$refs[0]} @{$refs[1]} \n";

output: 1 2 3 4 5 6

3. To get single elements out of the referenced arrays in @refs, try 
these expressions, whose values are identical:

	print "$refs[0]->[1]\n";  # -> de-refs $refs[0]
or
	print "${$refs[0]}[1]\n"; # { & } de-ref $refs[0]

output: 2         # in both cases


4. If you wanted a reference to an array that holds the combined 
values of @a and @b, then push those values into an array first and 
make a reference to the new array. Try

	$another_ref = [@a, @b];

	print "$another_ref \n";

	print "@$another_ref \n";

output: ARRAY(0x756339c)
	1 2 3 4 5 6

5.If your goal is to be able to push array values into a larger array 
using references, not at the outset but during processing, just 
remember not to mix apples and oranges (variables and references, in 
this case...).

Let's say you start with

	@a = (1,2,3);

	$new_refs = [@a];

and then later on you want to push @c's values into the array, try

	@c = (7,8,9);

	$c_ref = [@c];

	push @$new_refs, @$c_ref;  # The @ signs de-ref the array refs

	print "@$new_refs \n";

output: 1 2 3 7 8 9

6. So, let's turn back to your curious outputs:

>print "$#$refs\n"; results in -1 (huh?)
>print "$#refs\n"; results in 1 (correct...no $ reference in the array ref...)

a. The second one is straightforward: $#array_name gives the index of 
the last element of the array @array_name. Since you had array 
_references_, not array _elements_, stored in your array @refs, 
that's two elements, so the index is 1.

b. What does $#$refs mean? So far in your script, the scalar $refs 
hasn't been defined. With $# in front of it, Perl interprets the 
expression as giving the last element index of an array, but what 
array? It can only be an array referenced by $refs. Perl lets us 
create references without/before referencing something!!! Since $refs 
hasn't yet been assigned a value, the array it's a reference to has 
no elements. The index for the last item of an array with no elements 
is... -1  !

As a suggestion, start your scripts with -w on the shebang line, and 
learn from the Perl error messages (mistakes are our friends!). 
Unlike error messages from many programs, Perl's are quite helpful.

	#! perl  -w


HTH.

1;

- Bruce

__Bruce_Van_Allen___bva@cruzio.com__831_429_1688_V__
__PO_Box_839__Santa_Cruz_CA__95061__831_426_2474_W__


==== Want to unsubscribe from this list?
==== Send mail with body "unsubscribe" to macperl-webcgi-request@macperl.org