http://qs321.pair.com?node_id=931563

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

I am working on an older Perl version. Here are some details.
Perl version: 5.8.0 Redhat version: Red Hat 5.3
I want to open a file and read its contents. Below is the code. There is nothing special about the test_file.txt, it is just an ordinary text file.
#!/usr/bin/perl use warnings; use strict; use Switch; file_version_1(); file_version_2(); sub file_version_1 { open( my $fh, '<', '/tmp/test_file.txt' ) or die( "Error: $!" ); while( my $line = <$fh> ) { print "$line\n"; } close( $fh ); } sub file_version_2 { open ( FH, '/tmp/test_file.txt' ) or die ("Error: $!" ); while ( my $line = <FH> ) { print $line; } close( FH ); } sub test_switch { my $id = shift; switch( $id ) { case 'add' { print 'aa' }; } return 1; }
When the code is ran, this is what I get. The '111' is the content of the test_file.txt.
GLOB(0x98dfbdc) 111
Now, if I comment out the following:
use Switch; and sub test_switch { ... }
I get this result.
111 111
Now, if I try to run the original code in Perl 5.8.8, I would get the correct results.

So, it looks like the Switch module is causing this 'issue' on Perl 5.8.0. I also noticed that the version of Switch is 2.09 on 5.8.0 and 2.10 on 5.8.8.

I went further and ran this and got this. I am posting the snippet related to this.
$ perl -MO=Deparse test.pl ... die "Error: $!" unless open my $fh, '<', '/tmp/test_file.txt'; use File::Glob (); while (defined( my $line = glob( ' ' . $fh ))) { print "$line\n"; } close $fh
Is this a known bug for this module? Is it correct to say that the Switch module is doing some kind of source code filtering? If not, does anyone know why the original code is mis-behaving?

Replies are listed 'Best First'.
Re: Switch Module on Perl 5.8.0
by eyepopslikeamosquito (Archbishop) on Oct 14, 2011 at 20:48 UTC

    The Switch module mistakenly escaped into Perl 5.8. Do not use it. The Switch module was deprecated in Perl 5.10 and removed in Perl 5.14.

    Notice that in Categorized Damian Modules, the Switch module is categorized by its author as "Damian modules you shouldn't use in production because their purpose is to explore and prototype future core language features".

    You can switch to the built-in given/when if using Perl 5.10+. If stuck with Perl 5.8, I'd just use an if/elsif block instead.

    See also: stackoverflow question on why the Switch module is deprecated.

      See also "Basic BLOCKs and Switch Statements" in 5.8  perldoc perlsyn for a discussion of other switch-ish alternatives.

        See also Perl Best Practices Chapter 6 (Control Structures) especially:

        • 6.16 Value Switches - Use table look-up in preference to cascaded equality tests
        • 6.17 Tabular Ternaries - When producing a value, use tabular ternaries

      I'd agree with everything else everyone has said in this subthread, except this:

      The Switch module mistakenly escaped into Perl 5.8.

      Switch was deliberately put into Perl 5.8 for a very clear and specific purpose; a purpose that was eventually achieved in Perl 5.10.

      Think about it ;-)

      Damian

Re: Switch Module on Perl 5.8.0
by BrowserUk (Patriarch) on Oct 14, 2011 at 19:18 UTC

    Take a look at Switch::Perlish as a non-source filter alternative that is less likely to break in mysterious ways.


    With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    "Science is about questioning the status quo. Questioning authority".
    In the absence of evidence, opinion is indistinguishable from prejudice.
Re: Switch Module on Perl 5.8.0
by herveus (Prior) on Oct 14, 2011 at 18:11 UTC
    Howdy!

    Switch is a source filter, so that comes with extra-crunchy behavior at times. I'm not up on the fine details of where it will bite you, but that may be the case. What do you get from Deparse when you comment out "use Switch", etc.? The results you show certainly raise eyebrows.

    yours,
    Michael
      This is the output from Deparse when the 'use Switch' is commented out.
      die "Error: $!" unless open my $fh, '<', '/tmp/test_file.txt'; while (defined(my $line = <$fh> )) { print "$line\n"; } close $fh;
      When I saw this, I thought maybe the Switch module was adding the File::Glob statement but when I scanned the Switch module, I didn't immediately see why it would even do such a thing.