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

Hi, I have to write a script to do FTP file transfers that must run on Windows and Unix. For Windows, I will be using the Win32::Internet module and for Unix, I will be using the Net::FTP module. I have thought of several areas in which I might run into problems due to trying to get something to work transparently on both architectures and would appreciate any input into these situations as well as any I haven't thought of.

Creating an "FTPSession" Object for the Right Architecture at Runtime

This was discussed in a previous thread: Calling a class constructor as a function on input arguments

Trying to Include Modules Which Don't Exist for An Architecture

I think I have this one handled. I simply check $^O and do a run-time require as opposed to a compile-time use and thus only the modules existing for a particular architecture will be loaded on that architecture.

Code Will Have References to Variables and Functions (keywords) of the Modules for the Other OS

As I typed, I realized that one way to handle this is to move each arch's code into a different module and require the arch-dependent modules just as I do Win32::Internet and Net::FTP.

That being said, would there be compile-time errors if I used a single monolithic code body and made references to keywords of an unloaded module even if the code is never executed at runtime?

  • Comment on Managing Architecture-Dependant Perl Modules in an Object-Oriented Hierarchy

Replies are listed 'Best First'.
Re: Managing Architecture-Dependant Perl Modules in an Object-Oriented Hierarchy
by merlyn (Sage) on Sep 20, 2000 at 19:55 UTC
    One way would be to keep in mind that the use lib pragma adds an architecture-dependant directory below the directory you name. So you could place the version for Win under the "whatever windows is" subdirectory, and the other version under the other directory.

    Another would be to have a wrapper interface that does something like:

    BEGIN { eval 'require Win32::Internet'; unless ($@) { require MyWin32Wrapper; MyWin32Wrapper::->import(); } else { require Net::FTP; # Net::FTP::->import(); # OO interface - no need to do this require MyUnixWrapper; MyUnixWrapper::->import(); } }
    and then set up a common interface defined two different ways, depending on the success of requiring the Win32 version. So both of your wrapper files would define and export, say, fetch_file, but in different ways.

    -- Randal L. Schwartz, Perl hacker

Re: Managing Architecture-Dependant Perl Modules in an Object-Oriented Hierarchy
by chromatic (Archbishop) on Sep 20, 2000 at 19:44 UTC
    I wouldn't mingle architecture dependent stuff in one module. That's a formula for hard-to-read, harder-to-maintain C-style #ifdef code.

    That said, the Perl compiler will optimize away code paths that it can't possibly reach, like the following:

    while (0) { for (1 .. 1000000000) {} }

    Provided you have some sort of flag to mark sections of code as irrelevant to the current architecture, I think you'll be okay. (The disclaimer is that I haven't tried this in a while.)

    If I were doing this, I would write wrapper classes, as you suggest. This'll provide one consistent interface for your main module to use. Your wrappers can take care of massaging the divergencies.

    I'd write a tiny setup script that has the arch-dependent code in it, to check $^O and initialize the appropriate wrapper (which initializes the arch-dependent module). Then pass that wrapper instance into the constructor of the main module.

    That leaves your main module relatively clean, and puts the nasty stuff away elsewhere where you don't have to work around it when you're more concerned about the business rules in your main module.

      I'd much rather have the OS-dependent stuff in a module than repeated in every script that needs to portably do what is provided by several OS-specific modules! Modules are the best place for the "ugly" code that is sometimes needed.

      But, Net::FTP is already portable so there is no need to ever use Win32::Internet for doing FTP from Perl. Info about advantages of Win32::Internet over Net::FTP are welcome. I'm curious if there are any.

              - tye (but my friends call me "Tye")
        I found an advantage to Win32::Internet over standard portable alternatives.

        I had problems proxying https connections, but on Windows if I just used Win32::Internet it worked like a charm. Since I just needed a quick answer that ran on someone's desktop, I left it at that rather than worrying about SSLeay, etc (which really was not cooperating).

        Never tried to track down the proxying problem since I never had to, but if someone else has I wouldn't mind knowing what the issue was...