Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl: the Markov chain saw
 
PerlMonks  

Re: variable as hash name

by davido (Archbishop)
on Dec 08, 2012 at 04:36 UTC ( #1007854=note: print w/ replies, xml ) Need Help??


in reply to variable as hash name

After you fix the error message you're getting by removing "our" from line 9 (our %$variable ... just won't work), then you can move onto the strictures violation on line 13: print %$variable is still a strict violation even if you've already created the variable. If your code is going to be full of those constructs, you're going to have to run without strict 'refs', or jump through little "no strict 'refs'" contortions all over the place.

You say this is something you really want to do. So do it. Just don't ask "strict" to condone it.

use strict; use warnings; our $variable = 'name01'; no strict 'refs'; %$variable = ( valorC => 'value03', valorD => 'value04', ); print %$variable, "\n";

I'm interested in hearing why your code might fit into the 0.5% of code that needs to implement this powerful and dangerous feature. Are you writing an exporter? What is the benefit? Is it worth it? Are you sure it's not a problem that could be solved by another level of indirection? You might just need a 3rd floor, not a 2nd basement.


Dave


Comment on Re: variable as hash name
Select or Download Code
Re^2: variable as hash name
by blackzero (Acolyte) on Dec 08, 2012 at 05:19 UTC

    Thank you, Dave. Now, the point is that I'm reading an external file in the following format:

    230;238;101;103;138;146;112;116;; 230;238;101;103;146;146;108;112;; 224;238;0;0;146;146;110;118;; 238;238;0;0;146;146;112;114;;

    I have an array named @loci_codes with this content:

    @loci_codes = qw( Bet01 Bet05 Bet06 Bet12 );

    What I want is to read each line ( <> ), split and put the elements in an array

    while ( defined( $line = <> ) ) my @alelos = split ";", $line;

    Than I want to take the elements of @alelos two by two and put each pair in a different hash. The PROBLEM is that I want each of these hashes to be named after on of the elements of @loci_codes.

    while ( @loci_codes ) { $variable = shift @loci_codes; %$variable; $allele1 = shift @alelos; $allele2 = shift @alelos; %$variable{$allele1) += 1; %$variable{$allele2} += 1; }

    And doing that for each line of the input, I want to have a hash named after a element of @loci_codes and populated with these pairs.

    EXAMPLE:

    %Bet01 = ( 230 => 2, 238 => 5, 224 => 1,); %Bet05 = ( 101 => 2, 103 => 2, 0 => 4, ); ...

    NOTE: The content of @loci_codes may change according to the input file readed. THATS why I cant use static names for the hashes.

      %Bet01 = ( 230 => 2, 238 => 5, 224 => 1,); %Bet05 = ( 101 => 2, 103 => 2, 0 => 4, );
      Why not simply have "Bet01", "Bet05", ... as keys in a hash? For example:
      my %bets = ( 'Bet01' => { 230 => 2, 238 => 5, 224 => 1 }, 'Bet05' => { 101 => 2, 103 => 2, 0 => 4 }, );

        Because these 'groups' names ( that I want to use as hash names ) will also come from a external file.

      so how is that superior to using an explicit "name" level in your hash? Using a variable as a name simply introduces exactly the same effect as adding a "name" level to a hash, but you have no easy way to debug your code. If you use a conventional hash you can use modules like Data::Dump (or better still, use an IDE or the debugger) to inspect the contents of the hash for debugging purposes. Consider:

      #!/usr/bin/perl use strict; use warnings; use Data::Dump; my @loci_codes = qw( Bet01 Bet05 Bet06 Bet12 ); my %data; for my $dataIn ( qw( 230;238;101;103;138;146;112;116;; 230;238;101;103;146;146;108;112;; 224;238;0;0;146;146;110;118;; 238;238;0;0;146;146;112;114;; ) ) { my @alelos = split ";", $dataIn; for my $code (@loci_codes) { ++$data{$code}{shift @alelos}; ++$data{$code}{shift @alelos}; } } Data::Dump::dump(\%data); for my $code (@loci_codes) { print "$code: "; print join ', ', map {"$_ ($data{$code}{$_})"} sort {$a <=> $b} keys %{$data{$c +ode}}; print "\n"; }

      prints:

      { Bet01 => { 224 => 1, 230 => 2, 238 => 5 }, Bet05 => { "0" => 4, "101" => 2, "103" => 2 }, Bet06 => { 138 => 1, 146 => 7 }, Bet12 => { 108 => 1, 110 => 1, 112 => 3, 114 => 1, 116 => 1, 118 => +1 }, } Bet01: 224 (1), 230 (2), 238 (5) Bet05: 0 (4), 101 (2), 103 (2) Bet06: 138 (1), 146 (7) Bet12: 108 (1), 110 (1), 112 (3), 114 (1), 116 (1), 118 (1)
      True laziness is hard work

      I was hoping that you might come up with some interesting and compelling reason -- some problem that can only be solved by getting your hands dirty in the muck of the symbol table. Instead, I'm seeing a description of a problem that can be solved with one more layer of hard references; a hash of hashes, for example. That, you can read about in perldsc. GrandFather is right; you just need a higher level layer of abstraction; a hash of hashes.

      Your situation doesn't meet the criteria for a good reason to use symbolic references in any code that you intend to keep around on your hard drive for more than a few minutes. You've stated pretty clearly, however, that you're not open to other alternatives; you know what you want, and just needed us to show you how to do it. But as the old saying goes, "now you have two problems."

      It's easy to forget that the symbol table is little more than just a special hash. All of Perl's package globals live in hashes. Perl is implemented to hide that from you most of the time, but behind the scenes, they're there. You don't usually need to fiddle with Perl's hashes when you can create your own to fiddle with instead.


      Dave

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://1007854]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others romping around the Monastery: (9)
As of 2014-09-23 20:07 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    How do you remember the number of days in each month?











    Results (241 votes), past polls