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

this code makes me enter to directory of my choice and fro m config text read a value and then copies subdirectory and use the values read from config in new specified file in new created directroy . each time i run i get new directroy created but not the values in specified file. each time warning comes as use of uninitialized value $readline in string ne at newperlfile2.pl line 67,<CFILE> line3 use of uninitialized value $cSubVersId in concatenation (.) or string at newperlfile2.pl line 72 also the values read from config file is not present in the file in newly created directory...please help

#! C:/perl/bin/perl.exe use strict; use warnings; use File::Copy; use File::Basename; use Cwd; my $fullpath = cwd(); my $value = 0; opendir(my $pathindex, $fullpath ) or die "Couldn't read index : $!\n" +; while (my $currentfile = readdir($pathindex)) { print "current directory project $value\t"; print "$currentfile","\n"; $value++; } my $file = basename($fullpath); my $dir = dirname($fullpath); print "enter the project name with forward slash\n"; my $projectdir = <STDIN>; chop($projectdir); my $projectdirpath = "/"."$projectdir"; my $workingdirectory = ($fullpath.$projectdirpath); if(chdir($workingdirectory."/trunk")) { my $newpath = cwd(); } my $newpath = cwd(); my @searchfiles = ("rtl", "vhdl"); my $source_dirrtl; opendir(my $index, $newpath ) or die "Couldn't read index : $!\n"; while (my $file = readdir($index)) { print "$file","\n"; if ($file eq "rtl" ) { if(chdir($newpath."/rtl")) { my $currentworkingdir = cwd(); print "path = $currentworkingdir \n " ; $source_dirrtl = $currentworkingdir; } last; } elsif ($file eq "vhdl") { if(chdir($newpath."/vhdl")) { my $currentworkingdir = cwd(); print "path = $currentworkingdir \n " ; $source_dirrtl = $currentworkingdir; } last; } } my @words; my $readline; my $cChipId; my $cSubVersId; if(open (CFILE,"config.txt" ) || die $! ) { $readline = <CFILE>; while ($readline ne "") { @words = split(/\b[0-9][0-9][0-9][0-9]\b/,$readline); $readline = <CFILE>; } $cChipId = $words[0]; $cSubVersId = $words[1]; print "$cChipId \n"; print "$cSubVersId \n"; } #print("enter the chip id and subversion id \n"); #my $cChipId = <STDIN>; #my $cSubVersId = <STDIN>; #chop( $cChipId); #chop( $cSubVersId); my $source_dirsim = ("$newpath"."/sim"); my $source_dirsynth = ("$newpath"."/synth"); my $target_dirrtl1 = ("$newpath"."/rtl2"); my $target_dirsim1 = ("$newpath"."/sim2"); my $target_dirsynth1 = ("$newpath"."/synth2"); mkdir($target_dirrtl1,0777); mkdir($target_dirsim1,0777); mkdir($target_dirsynth1,0777); opendir(my $DIRRTL1, $source_dirrtl) || die "can't opendir $source_dir +rtl: $!"; opendir(my $DIRSIM1,$source_dirsim) || die "can't opendir $source_dirs +im: $!"; opendir(my $DIRSYNTH1,$source_dirsynth) || die "can't opendir $source_ +dirsynth: $!"; my @filesrtl1 = readdir($DIRRTL1); foreach my $t (@filesrtl1) { if(-f "$source_dirrtl/$t") { copy "$source_dirrtl/$t","$target_dirrtl1/$t"; } } my @filessim1 = readdir($DIRSIM1); foreach my $t (@filessim1) { if(-f "$source_dirsim/$t") { copy "$source_dirsim/$t","$target_dirsim1/$t"; } } my @filessynth1 = readdir($DIRSYNTH1); foreach my $t (@filessynth1) { if(-f "$source_dirsynth/$t") { copy "$source_dirsynth/$t","$target_dirsynth1/$t"; } } chdir("$target_dirrtl1"); my $m4file = "$projectdir".".m4"; print "$m4file"; if(open(MYFILE,">>$m4file")) { print MYFILE ("define(`m4_cChipId',`16#$cChipId#,16')\n"); print MYFILE ("define(`m4_cSubVersId',`16#$cSubVersId#,16')\n"); print MYFILE ("define(`m4_$projectdir',`1')\n"); my $output1 = `test.bat`; }

Replies are listed 'Best First'.
Re: warning: use of uninitialized value
by robby_dobby (Hermit) on Jun 25, 2015 at 06:14 UTC
    Hello mrityunjaynath,

    Welcome to the monastery. It's good that you have posted code but it's currently unreadable. Can you enclose them between <CODE></CODE> tags?

    There are several problems with your code:

    • You're creating variables that are not used anywhere - this is perfectly fine if you're debugging things, but it doesn't look logically structured in production code (or code used by someone other than you)
    • I see this convention of if(open($filehandle, "filename") || die $!) - this is really odd style. This means that whatever happens, straight or exceptional flow, go ahead an process this file. So you can see that it'll lead you down into errors. The general convention here is: open(my $fh, "filename.txt") or die "Couldn't open file:", $!;. See open - use 3-arg open form.
    • In the above point, note that I have used lexical filehandles rather than barewords. It's good form to use lexical filehandles.
    • File handles are scarce resources in some operating systems. Windows itself imposes a rather low limit on the number of open file handles. You should close file handles as soon as you're done processing them
    • Don't do $var ne "". Perl recognises non-defined values as false - so you can do: if(defined($var)) if you really need to check definedness (see defined) or just if($var), for a negative check: unless($var)

    Broadly speaking, you should logically structure your code - writing code is also a form of expression. You're expressing your thoughts to a dumb servant and it's very finicky about instructions. Otherwise, it's a lot of fun. It's also a good thing that perl itself comes with a lot of documentation. Keep referring to it, start from perlintro and continue on your path. Post here if you get stuck. Good luck!

    Enjoy.

      Hello robby_dobby,

      You make many good points. I would add:

      • Prefer chomp to chop when removing a terminal newline, as it’s safer.

      But I find this comment a bit strange:

      I see this convention of if(open($filehandle, "filename") || die $!) - this is really odd style. This means that whatever happens, straight or exceptional flow, go ahead an process this file.

      Of course, the if is entirely redundant here. But surely, if the code throws an exception (i.e., die is called), the file will never be processed?

      17:11 >perl -Mstrict -wE "say 'Ok 1'; if (open(my $fh, 'nonexistent.tx +t') || die $!) { say 'Ok 2'; } say 'Ok 3';" Ok 1 No such file or directory at -e line 1. 17:11 >

      Or have I misunderstood what you’re saying?

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

        for the OP might be worth only add few words about || and or: the high precedence || is valid and right as we put parens, without parens has another effect:
        use strict; use warnings; open my $fh, '<', 'notexistant.txt' or die qq(File open failed); #OK +: File open failed at open (my $fh, '<', 'notexistant.txt') || die qq(File open failed); #OK + too: File open failed at.. open my $fh, '<', 'notexistant.txt' || die qq(File open failed); #WR +ONG print <$fh>; # r +eadline() on closed filehandle $fh at..
        Just think of "and" and "or" as being the same as && and ||, but so low on the precedence chart that parenthesis are usually unnecessary to keep the things on the left or on the right properly grouped. It is almost always considered better to use "or" instead of "||" when you work with open.
        is a quote from a a very useful post about idioms and precedences: Perl Idioms Explained - && and || "Short Circuit" operators

        L*
        There are no rules, there are no thumbs..
        Reinvent the wheel, then learn The Wheel; may be one day you reinvent one of THE WHEELS.
        Hello Athanasius,

        No, you're completely right. I got distracted as I was typing this - this should remind me not to post when doing something. :-)

        Still, it stood out to me as weird that he relied on open's return value to check for success.

      hello sir i have enclosed with please see

      hii robby_dobby thanks for the suggestion. have applied those and the code is working without any warnings, but its not producing the output as desired. in the code i have opened config.txt, where you have suggested changes, in config file i have written chipid 1925 subversid 0001 and want only to read numeric value and use them but the code is picking only chipid string and using it. please tell me how should i write the code so that only numeric value is picked from config file please fine the code portion below

      if(open (my $CFILE,"config.txt" ) || die "couldnt open file:", $! ) { $readline = <$CFILE>; if (defined $readline ) { @words = split(/\b[0-9][0-9][0-9][0-9]\b/,$readline); $readline = <$CFILE>; } $cChipId = $words[0]; $cSubVersId = $words[1]; print "$cChipId \n"; print "$cSubVersId \n"; }

        Hello mrityunjaynath,

        If you say split(/X/, $string), then $string is split into chunks separated by whatever is matched by X. For example, in this one-liner:

        18:05 >perl -MData::Dump -wE "my $s = 'Hello1234world!5678How9012are34 +56you?'; my @w = split /[0-9]{4}/, $s; dd \@w;" ["Hello", "world!", "How", "are", "you?"] 18:06 >

        the string is split on 4-digit groups, and the array @w is populated with the words in $s which come between those digits.

        To capture the digit groups, you could try to split on non-digits, but it’s much better (and more straightforward) to use a regular expression with a /g modifier, like this:

        open(my $CFILE, '<', 'config.txt') or die "Couldn't open file 'config. +txt' for reading: $!"; $readline = <$CFILE>; @words = $readline =~ /([0-9]{4})/g;

        as demonstrated in this one-liner:

        18:06 >perl -MData::Dump -wE "my $s = 'Hello1234world!5678How9012are34 +56you?'; my @w = $s =~ /([0-9]{4})/g; dd \@w;" [1234, 5678, 9012, 3456] 18:18 >

        See split and perlretut.

        Hope that helps,

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

        Hello,

        Athanasius mentions a good point about using chomp instead of chop. I haven't completely looked at your code when I spotted those few errors.

        If others haven't got around to it before then, I'll reply back to you when I find the time.

Re: warning: use of uninitialized value
by kcott (Archbishop) on Jun 25, 2015 at 06:21 UTC

    G'day mrityunjaynath,

    Welcome to the Monastery.

    Your code is unreadable. A closing </code> may fix the problem; however, there could be other problems.

    Please use the [preview] button as many times as needed before hitting the [create] button.

    -- Ken

      hii ken i have already updated the code as per html view please check