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

I have an pl file that reads an xml and create another pl file. File is created by looping through an array. Issue is it writes for first element of array but not for further elements. I understand that it is perl features that it opens a file only once but how do I get past this issue and be able to write a file through out loop Also let me know if you have any other tips and comment for my code

use strict; use warnings; use diagnostics; use lib '/home/rahul/Documents/'; use script::filldataforlocator qw(clickfield send_keys_field); use script::readxmlcid qw(get_child_node_value); use script::getdata qw(connectdatabase); use XML::LibXML; my $module_used_file = $ARGV[1]; open(my $module_build_file_handle, '<', $module_used_file)or die "Coul +d not open file $module_used_file: $!"; my @module_file_lines = <$module_build_file_handle>; close $module_build_file_handle; my $dom = XML::LibXML->load_xml(location => $ARGV[0]); my $test_run_file_create = $dom->findvalue('//scenario/runname'); open(my $test_build_file_handle, '>', $test_run_file_create) or die "C +ould not open file '$test_run_file_create' $!"; foreach (@module_file_lines){ print $test_build_file_handle $_; } my @forms_required = ("createnewcid", "customerform"); my @child_node_values_fill; my $locatory_fields_id; my $locator_type; my $event_type; my $data_fill; my %hash_for_db_connect = ("companyname " => "contactnames", "contactn +ame" => "contactnames", "title" => "contactnames"); foreach my $config_forms (@forms_required) { @child_node_values_fill = get_child_node_value($config_forms); foreach (@child_node_values_fill) { ($locatory_fields_id, $locator_type, $event_type, $dat +a_fill) = split (/,/, $_); if (defined $locatory_fields_id && defined $locator_ty +pe && defined $event_type) { if ($event_type eq "click"){ print "My locator is $locatory_fields_id\n"; print $test_build_file_handle clickfield($loca +tory_fields_id, $locator_type)."\n"; print $test_build_file_handle "sleep(20)\;"."\ +n"; } elsif($event_type eq "send"){ if (defined $data_fill){ if (defined $hash_for_db_conne +ct{$data_fill}){ my $input_field_value += connectdatabase("$data_fill", "smartcidtest.$hash_for_db_connect{$d +ata_fill}"); print $test_build_file +_handle send_keys_field($locatory_fields_id, $locator_type, "$input_f +ield_value")."\n"; print $test_build_file +_handle "sleep(20)\;"."\n"; } } } } } } close $test_build_file_handle; chmod 0755, $test_run_file_create;

Replies are listed 'Best First'.
Re: Writing a file from foreach loop
by Athanasius (Archbishop) on Sep 19, 2017 at 07:33 UTC

    Hello rahulruns,

    Also let me know if you have any other tips and comment for my code

    This line:

    my %hash_for_db_connect = ("companyname " => "contactnames", "contactn +ame" => "contactnames", "title" => "contactnames");

    looks like a potential bug to me: do you really want “companyname” followed by a space as a hash key? I’m assuming not, in which case you can avoid the problem by taking advantage of the fact that Perl’s “fat comma” operator => quotes its left operand (see perlop#Comma-Operator), allowing you to write:

    my %hash_for_db_connect = (companyname => "contactnames", contactname +=> "contactnames", title => "contactnames");

    It’s also a good idea to delay the declaration of variables until they are actually needed, to avoid unnecessary variables altogether, and to use statement modifiers where possible. So this:

    ... foreach (@module_file_lines){ print $test_build_file_handle $_; } my @forms_required = ("createnewcid", "customerform"); my @child_node_values_fill; my $locatory_fields_id; my $locator_type; my $event_type; my $data_fill; my %hash_for_db_connect = ("companyname " => "contactnames", "contactn +ame" => "contactnames", "title" => "contactnames"); foreach my $config_forms (@forms_required) { @child_node_values_fill = get_child_node_value($config_forms); foreach (@child_node_values_fill) { ($locatory_fields_id, $locator_type, $event_type, $dat +a_fill) = split (/,/, $_); ...

    would be better written as the shorter and simpler:

    ... print $test_build_file_handle $_ for @module_file_lines; my %hash_for_db_connect = (companyname => 'contactnames', contactname +=> 'contactnames', title => 'contactnames'); for my $config_forms (qw( createnewcid customerform )) { for (get_child_node_value($config_forms)) { my ($locatory_fields_id, $locator_type, $event_type, $data_fil +l) = split /,/; ...

    Hope that helps,

    Athanasius <°(((><contra mundum Iustus alius egestas vitae, eros Piratica,

      Thank you for your review, it helps. But I still have question on entering data in a file in foreach loop

        Reduce your script down to the problem area and use Data::Dumper to debug it.

        #!/usr/bin/perl; use strict; use warnings; use Data::Dumper; use lib '/home/rahul/Documents/'; use script::readxmlcid qw(get_child_node_value); use XML::LibXML; my $dom = XML::LibXML->load_xml(location => $ARGV[0]); my @forms_required = ("createnewcid", "customerform"); foreach my $config_forms (@forms_required) { my @child_node_values_fill = get_child_node_value($config_forms); print Dumper $config_forms,\@child_node_values_fill; }
        poj
Re: Writing a file from foreach loop
by Anonymous Monk on Sep 19, 2017 at 06:27 UTC
    what is get_child_node_value and have you looked at what @child_node_values_fill contains?

      get_child_node_value provides child nodes from xml file which I am parsing and is passed to an array @child_node_values_fill