-6

I am new to perl and this thing is driving me nuts. I have a hash as below

%temp = (
  a_collection => [\%first, \%second]
)

I want to get the array elements out as a string so i can use them as args in the loop. I have below code

foreach $item (@{$temp{'a_collection'}})
{
  <convert to json> $item  #convert each of the above hash to a json blob
  <write to file> $file    #write first blob to file "first.json" and so on
}

I got the convert to json part. I can print it to stdout. Now i want to write it to a file. Here the $file should have name "first" and "second". So the loop will create two files with names of the hash variables which are there in the above hash. I want the filenames to match so i can keep track of whats getting created.

Edit : The basic premise is simple. Whatever i do, be it json encoding etc, i want the hash variable names as a string. So in the array above, i can have a hash with any name \%somename, in the loop i want the actual string "somename" in a different variable. As above, i can use this string as file name that gets created . I cannot change the above hash structure. Its just there, created by someone else, i can only access it.

Thanks

user775093
  • 589
  • 1
  • 8
  • 21
  • Your loop does not match the data structure you posted above it. What's the *actual* code you're using? – Matt Jacob Nov 19 '15 at 04:03
  • @user775093 what you actually trying? Are you referencing the hash inside the hash of array? If you want to do this, see below answer. Or anything else edit your post? – mkHun Nov 19 '15 at 04:22
  • 1
    You've completely changed the question, and it's still just as unclear as it was before, but the basic premise of my answer is still the same: hash keys. – Matt Jacob Nov 19 '15 at 05:06
  • 1
    @user775093 why you changed your question? You should have asked a new one. – Arunesh Singh Nov 19 '15 at 05:11
  • Because i was able to get the first part of what i wanted. I was referring to the hash variables anyways. The basic question is still the same.. I cannot change anything in the structure above . So i cant make "first" and "second" as hash keys. If i was allowed to do that I wouldnt have asked the question. – user775093 Nov 19 '15 at 07:16
  • So, why didn't you kept the whole question before, so that we can understand your requirement well from the begining. In this case it became XY problem because of uncomplete question. – Arunesh Singh Nov 19 '15 at 09:05
  • I will say why aren't you creating the filenames at the begining where you are declaring(or someone else declared) `%first` and `%second` hashes. If you would have done that, then there will be no need to get string out of your hash name. – Arunesh Singh Nov 19 '15 at 09:15
  • @user775093 You can't create hash keys named `first` and `second`, but you can create _hashes_ named `%first` and `%second`? Explain to me how that works. – Matt Jacob Nov 19 '15 at 16:42
  • in that case of course i can hard code the filenames etc. Of course i can do anything i want if it was possible. But its not and hence the question of how to get the names as string. If someone else adds a new hash in the file, i dont want to change my code to get that in json too. The same loop should work no matter what. The answer to a problem is not changing the problem.. – user775093 Nov 19 '15 at 17:39
  • Why don't you post your actual code instead of a contrived little example so that we can see where the data is coming from? (As I requested in my **first comment**...) – Matt Jacob Nov 19 '15 at 18:37

1 Answers1

0

Given the following code:

use strict;
use warnings;

my %first  = (foo => 2, bar => 3, bat => 5);
my %second = (baz => 7, quux => 11);
my %temp   = (a_collection => [\%first, \%second]);

for my $href (@{$temp{a_collection}}) {
    for my $key (keys(%$href)) {
        print "$key: $href->{$key}\n";
    }
}

This is the output produced:

bar: 3
foo: 2
bat: 5
quux: 11
baz: 7

Edit after new information was provided:

my %first  = (foo => 2, bar => 3, bat => 5);
my %second = (baz => 7, quux => 11);
my %temp   = (first => \%first, second => \%second);

for my $key (keys(%temp)) {
    print "$key\n";
}

Edit after yet more new information was provided:

use JSON::XS;

my %first  = (foo => 2, bar => 3, bat => 5);
my %second = (baz => 7, quux => 11);
my %temp   = (first => \%first, second => \%second);

for my $key (keys(%temp)) {
    open(my $fh, '>', "$key.json") or die $!;
    print $fh encode_json($temp{$key});
    close($fh);
}

Contents of first.json:

{"foo":2,"bat":5,"bar":3}

Contents of second.json:

{"quux":11,"baz":7}
Matt Jacob
  • 6,268
  • 2
  • 22
  • 27