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

Dear Monks, i have a construct which is more or less working (Dummy here, be kindly please).

%targets = ( '_source' => [], '_name'=> [] ); foreach my $ip1 (@ips){ foreach my $ref (@http){ for my $bla ( $ref->{'_source'}->{'clientip'} ) { if ($bla eq $ip1){ my $name = gethostbyaddr(inet_aton($bla), AF_INET); if ( $name !~ /.*\.dom1\.\.*.*./ ) { if ( $name !~ /.*\.dom2\.\.*.*./ ) { if ( $name !~ /.*\.dom3\.\.*.*./ ) { push @{ $targets{'_source'} }, $bla; push @{ $targets{'_name'} }, $name; } } } } } } }

What happens is that this code pushes all $bla to VAR1->_source and $name to VAR1->_name, like:

$VAR1 = { '_name' => [ 'carbon019.a.ahrefs.com', 'u17478488.onlinehome-server.com', ], '_source' => [ '181.167.186.3', '34.230.53.172', ] };
What i am trying to archive is to have a structure like:

VAR1->_source->$bla _name->$name VAR2->_source->bla _name->$name

and so on....May i ask a monk to help? I tried some stuff, but it didnt work. Thanks!!!

Replies are listed 'Best First'.
Re: Push to Reference
by haukex (Archbishop) on Oct 10, 2017 at 09:40 UTC

    It would be best if you could reduce your code down to only what is relevant to the question, so e.g. replace gethostbyaddr and those regexes by test data (see SSCCE). Also, you're using the Data::Dumper variable names VAR1, VAR2, etc., but haven't shown the call to Dumper(...), so we don't know which original variables those are. Anyway, based on your desired output, I am guessing that you want an "array of hashes", but your %targets is instead currently a "hash of arrays". It would probably be best if you read perlreftut and perldsc, the latter contains example code for both types of data structure.

    use Data::Dumper; my @targets; push @targets, { _source=>"s1", _name=>"n1" }; push @targets, { _source=>"s2", _name=>"n2" }; print Dumper(\@targets); __END__ $VAR1 = [ { '_source' => 's1', '_name' => 'n1' }, { '_name' => 'n2', '_source' => 's2' } ];
Re: Push to Reference
by VinsWorldcom (Prior) on Oct 10, 2017 at 11:07 UTC

    Looks like haukex may have solved your problem above, so just an observation:

    • It's 2017, we really should be using address family independent Socket routines.

    Unless you're *guaranteed* that:

    • @ips will only be IPv4 addresses, or
    • you're on a Perl older than 5.14, or
    • your Socket module version is older than 1.94, or
    • you're using an operating system circa Windows XP ...

    you may encounter IPv6. So planning for it is easy:

    #!perl use strict; use warnings; my @bla = qw ( 34.230.53.172 2607:f8b0:400d:c0b::63 ); for my $bla (@bla) { ### What you need below ### use Socket qw( AF_INET IPPROTO_TCP ); my $AF_UNSPEC = eval { Socket::AF_UNSPEC() }; my $NI_NAMEREQD = eval { Socket::NI_NAMEREQD() }; my %hints = ( family => $AF_UNSPEC, protocol => IPPROTO_TCP ); my ( $err, @getaddr ) = Socket::getaddrinfo( $bla, undef, \%hints ); for my $addr (@getaddr) { my ( $err, $host, $service ) = Socket::getnameinfo( $addr->{addr}, $NI_NAMEREQD ); printf "%s\n", ( defined($host) ) ? $host : $err; } ### What you need above ### }