Beefy Boxes and Bandwidth Generously Provided by pair Networks
There's more than one way to do things
 
PerlMonks  

How to name arrays via scalars.

by qingdaoghawk (Initiate)
on May 03, 2014 at 09:23 UTC ( [id://1084874]=perlquestion: print w/replies, xml ) Need Help??

qingdaoghawk has asked for the wisdom of the Perl Monks concerning the following question:

Hi, Monks! I am trying to creat a series of arrays whose names are the values of a series of scalars. Here is the code:

while(<FGLCS>){ chomp; ($scfd_name_frgt,$stt_pst_frgt,$stp_pst_frgt,$lgh_frgt)=split /\t/,$_; $scfd_name_frgt=reverse $scfd_name_frgt; unless($scfd_name_frgt eq $scfd_name_frgt_tmp){ $scfd_name_frgt_tmp=$scfd_name_frgt; @{$scfd_name_frgt}=($stt_pst_frgt,$stp_pst_frgt,$lgh_frgt); $frgtlocs{$scfd_name_frgt}=\@{$scfd_name_frgt}; } else{ push @{$frgtlocs{$scfd_name_frgt}},($stt_pst_frgt,$stp_pst_frgt,$lgh_f +rgt); } }

I wish to creat the arrays whose names are the values of the scalars "$scfd_name_frgt". But under "use strict", @{$scfd_name_frgt} is defined as dereference of reference of $scfd_name_frgt. How can I name arrays via scalars values under "use strict" ?

Replies are listed 'Best First'.
Re: How to name arrays via scalars.
by AnomalousMonk (Archbishop) on May 03, 2014 at 09:29 UTC

    Why it's stupid to `use a variable as a variable name'

    Update:

    c:\@Work\Perl\monks>perl -wMstrict -MData::Dump -le "use warnings; use strict; ;; my $foo = 'bar'; ;; my %data; push @{ $data{$foo} }, qw(zero one two three); dd \%data; ;; print qq{'$data{$foo}[1]'}; " { bar => ["zero", "one", "two", "three"] } 'one'

      Thanks for you advice. It is very helpful.

Re: How to name arrays via scalars.
by hdb (Monsignor) on May 03, 2014 at 10:04 UTC

    Due to a feature of Perl called Autovivification, you only need this:

    use strict; use warnings; while(<FGLCS>){ chomp; my ($scfd_name_frgt,$stt_pst_frgt,$stp_pst_frgt,$lgh_frgt)=split /\t +/,$_; $scfd_name_frgt=reverse $scfd_name_frgt; push @{$frgtlocs{$scfd_name_frgt}},($stt_pst_frgt,$stp_pst_frgt,$lgh +_frgt); }

    If @{$frgtlocs{$scfd_name_frgt}} does not exist, Perl just creates an array and you are done.

    UPDATE: Also looking at these two lines:

    @{$scfd_name_frgt}=($stt_pst_frgt,$stp_pst_frgt,$lgh_frgt); $frgtlocs{$scfd_name_frgt}=\@{$scfd_name_frgt};

    They can be abbreviated using square brackets to create a reference to an array:

    $frgtlocs{$scfd_name_frgt}=[$stt_pst_frgt,$stp_pst_frgt,$lgh_frgt];

    There is no need to create a named array first and then store a reference to it (if that is what you want).

      Thanks very much. Your answer has directly solved my problem. I now understand more about the reference.

Re: How to name arrays via scalars.
by Laurent_R (Canon) on May 03, 2014 at 09:58 UTC
    While you can use symbolic references under the use strict; pragma using the additional no strict refs; pragma and global variables, this is very generally considered as a (very) bad idea. It is much better practice to use one more level of reference in your data structure, such as an hash of arrays in your case (if I understand you correctly).

      Yeah, one more level can work. But it just need to be @{$genelocs{$scfd_name_gene}}=($a,$b,$c). Thanks anyway.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://1084874]
Approved by GrandFather
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others scrutinizing the Monastery: (12)
As of 2024-04-23 14:55 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found