That is close, but not exactly what I want to do.
I did not put enough detail in my starting post.
I have an array of values, the first one of which indicates what sort of data is in the array. I also have a set of arrays that indicate what fieldnames should be associate with the array.
Think of the array as sometimes being name and address, and sometimes name and phone number. I want to read $ARRAY[0] and then decide how the hash will be created. What I tried to do that does not work is this:
@Address=qw(type firstname lastname streetaddress city zip);
@Phone=qw(type name phonenumber);
%Stuff;
sub ReadStuff{
if ($@_[0]='addr') {%Stuff(@Address)=@_};
elsif ($@_[0]='phone'){%Stuff(@Phone)=@_};
...do something useful...
}
@data=(addr, bob, smith, 1234 main st, anytown, 20500);
&ReadStuff(@data);
@data=(phone, bob, smith, 212-555-1212)
&ReadStuff(@data)
But, of course, that does not work exactly like that, so I am trying to get close.
Skip | [reply] [d/l] |
#!/usr/bin/perl
use strict; # safety checks
use warnings; # useful hints
use Data::Dumper;
# notice the use of 'my' to declare a lexical scope
my @Address=qw(type firstname lastname streetaddress city zip);
my @Phone=qw(type name phonenumber);
sub ReadStuff {
# instead of using funny global variables, scope the
# hash within the subroutine, and return a reference at
# the end
my %Stuff;
# $_[0] is the first element of the array @_
# eq is the string equality test
# @h{@k} = @v is the syntax for hash slices
if ($_[0] eq 'addr') { @Stuff{@Address} = @_ }
elsif ($_[0] eq 'phone') { @Stuff{@Phone} = @_ }
# return a reference (as mentioned before)
return \%Stuff;
}
# let's quote our list elements this time
my @data1 = ('addr', 'bob', 'smith', '1234 main st', 'anytown', '20500
+');
my $stuff1 = ReadStuff(@data1);
my @data2 = ('phone', 'bob', 'smith', '212-555-1212');
my $stuff2 = ReadStuff(@data2);
# dump the results from both runs
print Dumper $stuff1;
print Dumper $stuff2;
Update: while this code does work, it doesn't quite do what your original question asks. That said, what you have here is probably exactly what I would suggest -- that is, keep the data in one place, and a list of keys in the other to tie it together. Using the structures this code creates, you could, for example, do $Stuff1->{$Address[4]} to get the field from $Stuff1 that corresponds to the key at index 4 from @Address. (whew! try saying that 5 times fast!) | [reply] [d/l] [select] |
Thank you.
I am currently crawling through the replies and making sense of them. I had to spend a couple of hours with use strict and use warnings turned on to clean up my lousy syntax.
Obviously I am a bit of a novice (to Perl, I have been whacking keys and writing bad code for about fifteen years). Yes, I have the Llama, access to a Camel, and the Cheeta.
Thank you all.
| [reply] |
Thank you very much for the recodeing. I have found it very edifying. It does work, and work quite well, and I am adding it to my mental perl toolset. But it does not do exactly what I need to do.
What I need to do is store the data in an array and access it from a hash. I need to be able to make a change using the a hash variable and have it affect the array variable.
You have shown me how to copy the data from an array into a hash using key names from another array. A valuable function, but not what I need.
Thank you,
Skip
| [reply] |
| [reply] [d/l] |
@Stuff{@{$Types{$_[0]}}} = @_;
This syntax is interesting. I have now copied it without fully understanding it. This part:
@{$Types{$_[0]}}
Seems to indicate, "Pull me the contents of this array element, and return it to me as an array". Am I correct?
The outer curly braces intrige me. I am sure that I read somewhere that the syntax should be:
@$Types{$_[0]}
Which I tried with little success. The braced version does work, but I hate to do things by magic. What do they mean?
Again, Thank you,
Skip | [reply] [d/l] [select] |