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

Hi - can't work this one out, which is frustrating me !

Trying to grab a subset of data from the data input - essentially, each network element and once I have that network stored in the array, check (grep) if the array contains the string 'dhcp-range', and if it does - do stuff.

I think I'm getting the 'Use of uninitialized value $_' error on the 2nd & 3rd end of network data lines ('</ip4-network>'), as those network elements stored in the array don't contain the 'dhcp-range' string. But ... I don't get why it's throwing the error !

On a side note, the data is XML, and I tried using XML::Simple to do stuff, but i want to diff two files in the end, and XML::Simple changed the data structure, so i reverted to this way instead

#!/usr/bin/env perl use strict; use warnings; use Data::Dumper; use 5.010; # declare my @net_configs; my @data = <DATA>; foreach my $confLine (@data) { # find start of a network, push to array if ( $confLine =~ /<ip4-network range/ ) { say "Found start of network !"; push( @net_configs, $confLine ); } # push other network lines onto array elsif ( @net_configs ) { push( @net_configs, $confLine ); # check for end of a network if ( $confLine =~ /<\/ip4-network>/ ) { say "Found end of network !"; if ( grep /dhcp-range/, @net_configs ) { say "Found a dhcp-range !"; foreach my $net_config (@net_configs) { print $net_config; } } @net_configs = undef; } } } __DATA__ <data> <configuration name="Test"> <ip4-network range="10.2.2.0/24"> <dhcp-range range="10.2.2.50 - 10.2.2.99"/> <dhcp-service-option name="next-server" value="10.1.2.3"/> <dhcp-client-option name="tftp-server-name" code="66" valu +e="10.1.2.3"/> <dhcp-client-option name="boot-file-name" code="67" value= +"boot.com"/> </ip4-network> <ip4-network range="10.2.4.0/24"> <ip4-address address="10.2.4.2" name="10.2.4.2" state="dhc +p-reserved" mac="AA-BB-CC-DD-EE-FF"/> <dhcp-service-option name="next-server" value="10.1.2.3"/> <dhcp-client-option name="tftp-server-name" code="66" valu +e="10.1.2.3"/> <dhcp-client-option name="boot-file-name" code="67" value= +"boot.com"/> </ip4-network> <ip4-network range="192.168.1.0/24"> <dhcp-service-option name="next-server" value="10.1.2.3"/> <dhcp-client-option name="tftp-server-name" code="66" valu +e="10.1.2.3"/> <dhcp-client-option name="boot-file-name" code="67" value= +"boot.com"/> </ip4-network> </configuration> </data>
Output:
Found start of network ! Found end of network ! Found a dhcp-range ! <ip4-network range="10.2.2.0/24"> <dhcp-range range="10.2.2.50 - 10.2.2.99"/> <dhcp-service-option name="next-server" value="10.1.2.3"/> <dhcp-client-option name="tftp-server-name" code="66" valu +e="10.1.2.3"/> <dhcp-client-option name="boot-file-name" code="67" value= +"boot.com"/> </ip4-network> Found start of network ! Found end of network ! Use of uninitialized value $_ in pattern match (m//) at zTweak.pl line + 32, <DATA> line 21. Found start of network ! Found end of network ! Use of uninitialized value $_ in pattern match (m//) at zTweak.pl line + 32, <DATA> line 21.

Thanks!

Replies are listed 'Best First'.
Re: Use of uninitialized value $_ in pattern match (m//)
by toolic (Bishop) on Mar 09, 2016 at 17:45 UTC
      For that matter, initialize

      my @net_configs = ();

        ... initialize my @net_configs = ();

        Why? What would  @net_configs look like if one were to depend on the default initialization of a newly-created lexical array?


        Give a man a fish:  <%-{-{-{-<

Re: Use of uninitialized value $_ in pattern match (m//)
by poj (Abbot) on Mar 09, 2016 at 18:16 UTC
    XML::Simple changed the data structure

    With an xml parser like XML::Twig you can build any data structure you want

    #!/usr/bin/env perl use strict; use warnings; use XML::Twig; my $t = XML::Twig->new( twig_handlers => { 'ip4-network' => \&network, }, pretty_print => 'indented', ); my $xml = do{local $/;<DATA>}; $t->parse($xml); sub network { my ($t,$e) = @_; my $range = $e->first_child('dhcp-range'); if ( defined $range ){ # do stuff print $range->att('range')."\n"; }; }
    poj
Re: Use of uninitialized value $_ in pattern match (m//)
by stevieb (Canon) on Mar 09, 2016 at 17:53 UTC

    @net_configs = undef; assigns an undef as the first and only element in the @net_configs array, so next loop through, it triggers the elsif, because the array is not empty.

    Instead, undef the array as such:

    undef @net_configs;

    ...or as others have stated, just re-initialize the array.

Re: Use of uninitialized value $_ in pattern match (m//)
by stroke (Acolyte) on Mar 09, 2016 at 19:09 UTC

    Perfect. Thanks. I was using Data::Dumper, but just couldn't see the simple mistake I was making.

    I'll take another look at the XML processing with XML::Twig - thanks