in reply to Re: Warnings not working on one machine
in thread Warnings not working on one machine

Hi folks, thanks for your replies. I get the same results for both machines:
me@BothMachines: perl -e'use warnings; print undef; print "done\n";' Use of uninitialized value in print at -e line 1. done me@BothMachines: cat test.pl #!/usr/bin/perl use strict; use warnings; print undef; print "done\n"; me@BothMachines: ./test.pl Use of uninitialized value in print at ./test.pl line 4. done
After playing around a bit more I realised that the location in the code where this is happening is in another perl file which I include by require. The included file does not have use statements. Are the use strict; and use warning; only applied to the current file, and not those included by require?

However, this still does not explain why it shows the warnings on one machine and not the other. I can't post work-code here, but I will construct an simple example that is equivalent and post here.

Replies are listed 'Best First'.
Re^3: Warnings not working on one machine
by questions (Initiate) on Jan 26, 2018 at 13:09 UTC
    So, here are some examples of code producing different results on both machines. test2.pl runs alone by itself, test3.pl does the exact same tasks but uses the test3_utils.pl file. In both cases, warnings and variable contents differ per machine.
    cat test2.pl #!/usr/bin/perl use strict; use warnings; use Cwd; use File::Basename; use List::Util qw(min max); use Math::Round; use Sort::Key::Natural qw(natsort); use Storable 'dclone'; use Sys::Hostname; use Term::ANSIColor; print "decimal places: ".length(("1" =~ /\.(\d*)/)[0])."\n"; print "decimal places: ".length(("0.123" =~ /\.(\d*)/)[0])."\n"; my $line = "apple="; my $second_part = (split(/=/, $line))[1]; my $second_part_components_count = (length $second_part > 0 ? scalar ( +split(/;/, $second_part)) : 0); print "done\n"; cat test3.pl #!/usr/bin/perl use strict; use warnings; use Cwd; use File::Basename; use List::Util qw(min max); use Math::Round; use Sort::Key::Natural qw(natsort); use Storable 'dclone'; use Sys::Hostname; use Term::ANSIColor; require "test3_utils.pl"; do_foo(); do_bar(); print "done\n"; cat test3_utils.pl #!/usr/bin/perl sub do_foo { print "decimal places: ".length(("1" =~ /\.(\d*)/)[0])."\n"; print "decimal places: ".length(("0.123" =~ /\.(\d*)/)[0])."\n"; } sub do_bar { my $line = "apple="; my $second_part = (split(/=/, $line))[1]; my $second_part_components_count = (length $second_part > 0 ? scal +ar (split(/;/, $second_part)) : 0); } 1; # need to end with a true value

    The scripts are copied to the second computer (SciLnx) where they produce different results:

    me@UbuntuMachine: ./test2.pl Use of uninitialized value in concatenation (.) or string at ./test2.p +l line 14. decimal places: decimal places: 3 Use of uninitialized value $second_part in numeric gt (>) at ./test2.p +l line 19. done me@UbuntuMachine: ./test3.pl decimal places: decimal places: 3 done me@SciLnxMachine: ./test2.pl Use of implicit split to @_ is deprecated at ./test2.pl line 19. Use of uninitialized value in length at ./test2.pl line 14. decimal places: 0 decimal places: 3 Use of uninitialized value $second_part in length at ./test2.pl line 1 +9. done me@SciLnxMachine: ./test3.pl decimal places: 0 decimal places: 3 done
    I would expect the same results and the same warnings on both machines. To my surprise, neither is the case. The SciLnx is returning 0 where the Ubuntu machine is returning nothing.

    The software in question is distributed to partners, it is important that it does what we expect. Is there any way to investigate what is causing this behavioural difference?

      In Perl 12 Delta one of the Other potentially incompatible changes is ;

      length undef now returns undef.

      Update Possible fix ? length(("1" =~ /\.(\d*)/)[0] || '')

      poj
      In both cases, warnings and variable contents differ per machine.

      Not quite. If you look closely at your outputs, the warnings in test3.pl do not differ between the machines. This is because there are no warnings because the code which would generate them is in test3_utils.pl which does not have warnings enabled.

      But not having the warnings enabled is a bad thing because you would miss important points like "Use of implicit split to @_ is deprecated at ./test2.pl line 19." in the older perl. Since you don't see this in the newer perl it's safe to say that it has moved from "deprecated" to "deleted" and hence the code behaves differently. When you first saw that warning in the older perl version you should have taken steps then to code around it and you might not have the problem now in the newer perl version.

      Always use warnings and always fix any which are reported.

      Update: Here's an example rewrite of test2.pl which produces no warnings and the same output on both v5.10.1 or v5.20.3:

      use strict; use warnings; sub ndp { $_ = shift or return 0; /\.(\d*)/ and return length ($1); return 0; } print "decimal places: " . ndp ('1' ) . "\n"; print "decimal places: " . ndp ('0.123') . "\n"; my $line = "apple="; (undef, my $second_part) = split (/=/, $line); my $second_part_components_count = length $second_part ? scalar (my @f +oo = split /;/, $second_part) : 0; print "done\n";

      No doubt it could be neater but hopefully it illustrates some approaches for you.

        Thanks for your replies. I guess I have to put the use warnings; into both the calling script and the called utilities library, which is what I have now done.

        I was hoping the use warnings; in the calling script would have been enough to ensure all called libraries had the same warnings behaviour when used by that script. That way the same library could be used by different scripts with different warnings behaviour. Not sure if they had other concerns in mind when they decided to make it like this, but I'm happy that I now finally know what's going on and how to make it work for me.

        Thank you for your assistance!