in reply to code that runs (and works) on both Linux and Win32

Untested code below. The trick? Pretend modules you don't want to load under certain conditions are already loaded.
BEGIN { if ($^O =~ /Win32/) { $INC{"Device/SerialPort.pm"} = 1; } else { $INC{"Win32.pm"} = 1; $INC{"Win32/TieRegistry.pm"} = 1; $INC{"Win32/SerialPort.pm"} = 1; } } use Device::SerialPort; use Win32; use Win32::TieRegistry; use Win32::SerialPort; .. rest of your logic ...
Alternatively, use the if module:
use if $^O =~ /Win32/, "Win32"; use if $^O =~ /Win32/, "Win32::TieRegistry"; use if $^O =~ /Win32/, "Win32::SerialPort"; use if $^O !~ /Win32/, "Device::SerialPort";