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

I have to write an array to a file, basically export the array variable , and then read it back from the file

the array is populated in the following manner

   eval(" push \@reg_map${page_counter},\[\"\$var01\",\$var00,\"$var02\"\]");

reg_map is the array which i need to write/dump/export in to a file as it is and then imported/retrieved in the same format .. Can this be done in some way .. using Dump/Export/Store

Replies are listed 'Best First'.
Re: Writing indexed arrays in to an file and then retrieved
by stevieb (Canon) on Oct 28, 2015 at 16:51 UTC

    Using Storable:

    use Storable; store(\@array, 'file.ext'); my $aref = retrieve('file.ext');

    JSON is also a good choice, and it's cross language/platform. ie. I can get the data from the file in Python after writing it in Perl:

    use warnings; use strict; use JSON; my @array = qw(1 2 3); open my $wfh, '>', 'file.ext' or die "can't open file for writing: $!"; print $wfh encode_json(\@array); close $wfh; open my $fh, '<', 'file.ext' or die "can't open file for reading: $!"; my $aref = decode_json(<$fh>); close $fh;

      Thanks Stevieb for the response .. and everyone else .. But somehow it does not work .. or may be i am not doing it right If i print the reg_map variable using the following code

      for $i ( 0 .. $page_counter-1 ) { print " ###### HI $i #### \n"; eval ( "\$Total_Size = \$\#reg_map${i}"); print " Total Size = $Total_Size\n"; for $j1 ( 0 .. $Total_Size ) { eval ("\$Num_elements_in_row = \@\{\$reg_map${i}\[\$j1\]\}"); print " Num_elements_in_row $j1 is = $Num_elements_in_row\n"; for $j3 ( 0 .. $Num_elements_in_row ) { eval("print \"Bit 1 :\$i:\$j1:\$j3 is \$reg_map${i}\[\$j1\]\[\$j +3\]\n\""); } } }

      I get the following display

      Total Size = 80

      Num_elements_in_row 0 is = 3

      Bit 1 :0:0:0 is NONE

      Bit 1 :0:0:1 is NONE

      Bit 1 :0:0:2 is NONE

      Bit 1 :0:0:3 is

      Num_elements_in_row 1 is = 4

      Bit 1 :0:1:0 is TEMP

      Bit 1 :0:1:1 is 0

      Bit 1 :0:1:2 is .

      Bit 1 :0:1:3 is 1

      Bit 1 :0:1:4 is

      I used Store as follows

       store(\@reg_map, 'file.ext');my $aref = retrieve('file.ext');

      When i print aref using the code below

      for $i ( 0 .. $page_counter-1 ) { print " ###### HI $i #### \n"; eval ( "\$Total_Size = \$\#aref${i}"); print " Total Size = $Total_Size\n"; for $j1 ( 0 .. $Total_Size ) { eval ("\$Num_elements_in_row = \@\{\$aref${i}\[\$j1\]\}"); print " Num_elements_in_row $j1 is = $Num_elements_in_row\n"; for $j3 ( 0 .. $Num_elements_in_row ) { eval("print \"Bit 2 :\$i:\$j1:\$j3 is \$aref${i}\[\$j1\]\[\$j3\] +\n\""); } } }

      I get the following

      ###### HI 0 ####

      Total Size = -1

      ###### HI 1 ####

      Total Size = -1

      I Also tried using JSON as follows

      open my $wfh, '>', 'file1.ext' or die "can't open file for writing: $!"; print $wfh encode_json(\@reg_map); close $wfh; open my $fh, '<', 'file.ext' or die "can't open file for reading: $!"; my @aref = decode_json(<$fh>);

      But i get an error at the last line :

      malformed JSON string, neither array, object, number, string or atom, at character offset 0 (before "pst0\x{4}\x{8}\x{8}1...") at perl_script.pl line 100, <$fh> line 1.

      Any thoughts on this ..

         eval "..."

        now is a good time to stop writing code like that :)

Re: Writing indexed arrays in to an file and then retrieved
by shmem (Chancellor) on Oct 29, 2015 at 11:47 UTC
    the array is populated in the following manner
    eval(" push \@reg_map${page_counter},\[\"\$var01\",\$var00,\"$var02 +\"\]");

    Eek. So you have something like @reg_map00,@reg_map01,@reg_map02,..?

    Whenever you are tempted to add a counting suffix to any variable, use an array instead:
    • Instead of @reg_map00,@reg_map01,@reg_map02 use @reg_map - $reg_map[0], $reg_map[1], $reg_map[2]. If you want to store arrays in those slots, use anonymous arrays.
    • Instead of $var01,$var00,$var02 use @var - $var[1], $var[0], $var[2]
    No need for eval then:

    push @{$reg[$page_counter]}, @var;

    Think of eval as a costly subshell under the control of you program in its own sandbox1. Setting that up only to push to an array is overkill, convoluted, difficult to read and maintain.

    Whenever you are tempted to use variables using a stem and a suffix, e.g. $some_foo, $some_bar, $some_baz - use a hash instead:

    %some = ( foo => ..., bar => ..., baz => ..., ... );

    This makes your code cleaner, more readable, more maintainable, and it makes constructs like your eval push unnecessary.

    1) Not quite a sandbox proper, since even string eval gets the surrounding lexicals, let alone (package) globals.

    perl -le'print map{pack c,($-++?1:13)+ord}split//,ESEL'
A reply falls below the community's threshold of quality. You may see it by logging in.