in reply to Re: Easing cross-platform scripting
in thread Easing cross-platform scripting

module that loads either Win32::SerialPort or Device::SerialPort, although they both provide a very similar API
I've done something like that...not an "Any" module, but conditionally loading one or the other. You do need to wrap it in a BEGIN block and eval, due to the way "use" works:
# # Use Win32::Serial port on Windows otherwise, use Device::SerialPort #; BEGIN { my $IS_WINDOWS = ($^O eq "MSWin32" or $^O eq "cygwin") ? 1 : 0; # if ($IS_WINDOWS) { eval "use Win32::SerialPort"; die "$@\n" if ($@); } else { eval "use Device::SerialPort"; die "$@\n" if ($@); } }
Then something like this when using it:
my $IS_WINDOWS = ($^O eq "MSWin32" or $^O eq "cygwin") ? 1 : 0; if ($IS_WINDOWS) { $serial = new Win32::SerialPort ($port, 1); } else { $serial = new Device::SerialPort ($port, 1); }
Somewhat ugly, but handy for anyone using my module. There's likely some more elegant way to do it.

Replies are listed 'Best First'.
Re^3: Easing cross-platform scripting (conditional module loading)
by hippo (Archbishop) on Nov 27, 2018 at 22:38 UTC

    One arguably more elegant way would be with the if pragma. The documentation even uses this specific case (yes/no MSWin32) as the first example.

    Another could be Module::Load which can be used for run-time decisions (as opposed to compile-time) and might therefore be better suited to more general cases.

Re^3: Easing cross-platform scripting
by haukex (Archbishop) on Nov 28, 2018 at 15:30 UTC

    Thanks for the example - just to pick a couple nits:

    • eval "..."; die $@ if $@; has issues, eval "...; 1" or die $@; is better
    • Indirect Object Syntax is discouraged, Win32::SerialPort->new($port, 1) is better
    • Instead of evaling a use, in this case a require is enough.
    • You don't need the duplicate $IS_WINDOWS, it's easier to do my $IS_WINDOWS; BEGIN { $IS_WINDOWS = ...