Beefy Boxes and Bandwidth Generously Provided by pair Networks
Come for the quick hacks, stay for the epiphanies.
 
PerlMonks  

Problem with ``use if COND, Some::Module'' on Linux

by stevieb (Canon)
on Apr 08, 2016 at 16:54 UTC ( [id://1159936]=perlquestion: print w/replies, xml ) Need Help??

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

Hey all,

On Windows (2012 server, running perl 5.22.1), I get expected results using use if ...;:

use if $^O !~ /MSWin/, "Proc::Daemon"; use if $^O =~ /MSWin/, "Win32::Daemon"; print "$INC{'Win32/Daemon.pm'}\n"; exit; __END__ C:/berrybrew/5.22.1_64/perl/vendor/lib/Win32/Daemon.pm

But on Ubuntu, running v5.22.1:

use if $^O !~ /MSWin/, 'Proc::Daemon'; use if $^O =~ /MSWin/, 'Win32::Daemon'; print "$INC{'Proc/Daemon.pm'}\n"; exit; __END__ Too few arguments to 'use if' (some code returning an empty list in li +st context?) at /home/ubuntu/perl5/perlbrew/perls/perl-5.22.1/lib/5.2 +2.1/if.pm line 7. BEGIN failed--compilation aborted at /home/ubuntu/perl5/perlbrew/perls +/perl-5.22.1/bin/bbtester line 6.

I can't really find anything about this being a known problem. Proc::Daemon is properly installed (as I can use it in a module without the conditional use):

perl -MProc::Daemon -E 'say $Proc::Daemon::VERSION' 0.23

Can anyone spot anything I'm doing wrong, or is this something that just doesn't work reliably?

Update: I just realized that this was my 1,000th post here on PerlMonks :)

Replies are listed 'Best First'.
Re: Problem with ``use if COND, Some::Module'' on Linux
by 1nickt (Canon) on Apr 08, 2016 at 17:30 UTC

    " ... (some code returning an empty list in list context?) ... "

    Nothing to do with Proc::Daemon, but with the pattern match that returns an empty list:

    use strict; use warnings; use if scalar ( $^O !~ /Win32/ ), 'Proc::Daemon'; use if scalar ( $^O =~ /Win32/ ), 'Win32::Daemon'; print $INC{'Proc/Daemon.pm'}; exit; __END__
    Output:
    perl 1159936.pl /Users/nick/perl5/perlbrew/perls/perl-5.22.0/lib/site_perl/5.22.0/Proc +/Daemon.pm

    Hope this helps!

    Updated: force scalar context so we can keep pattern matches


    The way forward always starts with a minimal test.

      Yep, that works if I do ne 'MSWin32', but I'm very curious to know why my way works on Windows but not on nix.

      The whole reason for the !~, =~ is so I don't have to check for both MSWin32 and MSWin64.

        Not for nothing, but is 'MSWin64' an actual OS string? I'm on Windows 7 x64 with Strawberry Perl 5.22 64-bit and $^O still returns "MSWin32" for me.

        VinsWorldcom@C:\Users\VinsWorldcom> ver Microsoft Windows [Version 6.1.7601] VinsWorldcom@C:\Users\VinsWorldcom> perl -v This is perl 5, version 22, subversion 1 (v5.22.1) built for MSWin32-x +64-multi-thread [...] VinsWorldcom@C:\Users\VinsWorldcom> perl -e "print $^O" MSWin32

        The following works...

        my $is_win = $^O =~ /MSWin/ ? 1 : 0; use if $is_win, 'Win32::Daemon'; use if ! $is_win, 'Proc::Daemon';

        Updated to force scalar context on the pattern match output.

        The way forward always starts with a minimal test.
Re: Problem with ``use if COND, Some::Module'' on Linux
by RonW (Parson) on Apr 08, 2016 at 17:46 UTC

    The "hint" in the error message provides a big clue.

    The arguments to use if are evaluated in list context. Therefore the match expressions are being evaluated in list context.

    From the Perl documentation: "When there are no parentheses in the pattern, the return value is the list (1) for success. With or without parentheses, an empty list is returned upon failure."

    So, on a non-MSwindows platform, $^O =~ /MSWin/ is returning an empty list.

    Of course, on MSwindows, $^O !~ /MSWin/ is failing, but because it has an implied not, it is equivalent to not ($^O =~ /MSWin/) so is returning a non-empty false value.

        Quack

Re: Problem with ``use if COND, Some::Module'' on Linux
by Anonymous Monk on Apr 08, 2016 at 19:55 UTC
    See Devel::CheckOS
    use Devel::CheckOS qw/ os_is /; use if os_is(qw/ Win32 /), 'Win32::Daemon'; use if !!os_is(qw/ Win32 /), 'Proc::Daemon';
Re: Problem with ``use if COND, Some::Module'' on Linux
by ww (Archbishop) on Apr 08, 2016 at 17:48 UTC

    Kludge, alternate, but seems that Ubuntu may ("MAY!") prefer this syntax, which works on both MSWin7 (64) and Ubuntu 14.04 and produces the expected output:

    # 1159936 revising stevieb's OP use if ( $^O !~ /MSWin/ ), 'Proc::Daemon'; { print "$INC{'Proc/Daemon.pm'}\n"; } use if ($^O =~ /MSWin/), 'Win32::Daemon'; { print "$INC{'Win32/Daemon.pm'}\n"; } exit;
    If you didn't program your executable by toggling in binary, it wasn't really programming!

      That doesn't fix the problem on my Ubuntu (or Darwin):

      $ lsb_release -a No LSB modules are available. Distributor ID: Ubuntu Description: Ubuntu 14.04.3 LTS Release: 14.04 Codename: trusty
      Code:
      use if ( $^O !~ /MSWin/ ), 'Proc::Daemon'; { print "$INC{'Proc/Daemon.pm'}\n"; } use if ($^O =~ /MSWin/), 'Win32::Daemon'; { print "$INC{'Win32/Daemon.pm'}\n"; } exit;
      Output:
      Too few arguments to 'use if' (some code returning an empty list in li +st context?) at /home/vagrant/perl5/perlbrew/perls/perl-5.16.3/lib/5. +16.3/if.pm line 7.


      The way forward always starts with a minimal test.

      Update: I was mistaken. I didn't test both conditions... the latter one did break.

      Thanks ww, I honestly could have sworn that I tested that, but I couldn't have, as wrapping the condition within parens does in fact work properly.

        Really? On Ubuntu 14.04? Not for me ...

        The way forward always starts with a minimal test.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://1159936]
Front-paged by Arunbear
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others admiring the Monastery: (3)
As of 2024-04-19 19:54 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found