![]() |
| ![]() |
||||||||||||||||||||||||||||||||||||||||||||||||
|
Script Different Vicki Brown MacPerl Oddities: if ($^O eq 'MacOS')In many ways, MacPerl is no different from "regular" (that is, Unix) Perl. Much of the functionality you would expect to find is there. Most of the books that are available for Perl apply to MacPerl; many of the available scripts run in both environments. In short, MacPerl is "real" Perl and it is quite possible to write scripts which will function in both Mac and Unix environments. In some ways, however, MacPerl is vastly different. Recognizing those differences will help you to understand why scripts you might pick up from the net, or modules you download from CPAN (the Comprehensive Perl Archive Network), may not simply "plug and play" without some effort on your part. Understanding the differences may also help you to write programs that are more portable to other platforms. (After all, there's that "Redmond operating system" that isn't Unix or Linux either :-) #!perlMany Perl programs begin with the string #!/path/to/perlwhere /path/to/perl is usually /usr/local/bin/perl or /usr/bin/perl. The path is optionally followed by switches, such as -w or -T. On Unix systems, the #! line is magical - it is a directive to the Unix kernel, providing the actual path to the program that should be used to run the script, as if that command were given on the command line. Unix launches the specified program, with any flags as given, and hands it the file in question as an argument, as if you had entered /usr/bin/perl -w myfilenameVoila! Instead of a "shell script" (executed by the Unix shell), we now have a "real program" - an executable script that can "invoke" its own interpreter. In contrast, the Macintosh has no command line. Applications are launched by double-clicking. Mac "documents" (i.e., scripts) tell the Finder what program to run by means of their Creator ID, a 4-character string that uniquely identifies each Mac application (MacPerl's Creator ID is McPL). You might think that the #! line wouldn't be of any use on a Macintosh. It can contain more information than just the path to Perl, however; for example, it may contain optional switches, such as -w. To take advantage of the usefulness of the #! construct (and for better portability of scripts!), MacPerl emulates the Unix handling of the #! line. Because of the way #! is implemented, however, some Perl switches cannot be included in it when using MacPerl. If you try, you'll get an error message: # Can't emulate -x on #! line.or # Too late for "-T" option. Oh. You may be wondering whether you need to specify the path to MacPerl, and how this could possibly help enhance portability! Actually, MacPerl doesn't care what you use as the path, as long as what you use includes the word "perl". So for simple, Mac-only scripts, you can just use #!perlwhile for scripts you plan to move to Unix, you can specify the correct path to perl for the Unix system. \n and \rOn Unix systems, the default line-ending character (record separator or $/) is the line feed (ASCII \012). On Mac OS, it's the carriage return (\015). On MS-DOS and Windows systems, it's the sequence "carriage return line feed" (\012 \015). Perl uses \n to represent a "newline", which Unix systems interpret as a line feed character. For portability, the \n in MacPerl outputs a carriage return (the Mac OS "newline" character). You should also note that, although \n produces a "carriage return" (\015) under MacPerl, \r (which produces a return without a newline under Unix Perl), produces a line feed under MacPerl. Programs that use \r to back up to the beginning of a line (without moving to the next line) will not exhibit the expected behavior under MacPerl. Beware. Carriage returns and line feeds may sometimes cause difficulties if you download scripts or modules from the Internet. If you use a "smart" FTP client (such as Fetch or Anarchie), proper translation should be done for you. However, if you ever try to run a script or module and get a strange error message, such as # Illegal character \012 (carriage return).check whether the script file may have been munged in transition. Running commands: system() and backquoted commandsUnless you are using ToolServer (part of MPW, the Macintosh Programmers Workbench suite), the system() function will not work under MacPerl. A few backquoted commands, such as `pwd` and `hostname`, are emulated; however, the number available is small. Even with ToolServer, the only commands you will be able to use will be MPW commands. Unfortunately, if you start picking up Perl scripts from the Net, you will find that many of them make use of system() and backquoted commands. The good news is that many of these scripts can be modified to run under MacPerl by rewriting these calls in native Perl code. You may have to do a little research, and you may need to get creative, but give it a try before you give up. Here are some common Unix commands that may be found in system() statements, along with their Perl equivalents:
Processes: fork, exec, waitUnfortunately, the current Mac OS is not designed to fork and execute processes in the same way that a Unix system does. These functions are not implemented, and no good workarounds are available. If you pick up a Perl script that forks subprocesses, you're probably in for a difficult porting effort. You may want to try to find some other way to solve the problem... User protocols, network protocols, process managementGiven that the Macintosh has no facility for logging in, no password file, and only a minimal concept of "users", it may come as no surprise that many of the functions that relate to user activity are not implemented. These include such functions as chown, getpwnam, and so on. Similarly, Unix Perl includes a fairly large number of functions which handle network protocols (such as getnetbyaddr, getprotoent) and process management (chroot, getlogin, getppid). These have no meaning on a Macintosh and so are unimplemented. TimeBoth Unix and the Mac OS view time as the number of seconds since the epoch (the "beginning of time"). Unfortunately, the two operating systems have different definitions of when the epoch began! Unix, and Unix Perl, count time from January 1, 1970. Mac OS and MacPerl, in contrast, count time from January 1, 1904. The various time functions, such as localtime(), have been modified to take this difference into account. However, if you work with raw time values, such as those returned by time(), or port your code to another operating system, be wary. For example, you may know that a numeric string (e.g., 1241299336) represents a particular date/time value (e.g., the date a Web cookie expires). It can make a big difference, however, where you run the Perl script to convert this number into a human-readable date! The following code $t = localtime(1241299336); print $t;prints very different values on Unix vs. Mac Perl Sun May 2 21:22:16 1943 # Mac Sat May 2 14:22:16 2009 # Unix Filename GlobbingUnder Unix, the glob() function (and the shorthand globbing operator, <>) invoke the C shell (csh) to handle filename expansions. Under Mac OS, the C shell is not available, so MacPerl implements filename globbing itself. Unix Perl has a few extra metacharacters available for glob patterns, such as character classes (e.g., [a-f]*). MacPerl currently supports only two metacharacters: * matches any number of characters; ? matches a single character. PathnamesIf you pick up Perl scripts from the net, try out examples from books on Perl, or move a script from Mac OS to a Unix machine, sooner or later you will run into differences in pathnames. On Unix systems, pathnames are relatively common; it's difficult to spend very much time entering commands from a command line without using pathnames! However, because of the Mac's point and click, drag and drop interface, Mac OS users can go for a long time without even knowing about pathnames, much less getting used to employing them! Mac OS pathnames and Unix pathnames have many things in common. Users of both operating systems can specify either absolute (full) or relative paths, where the last element of the path can be a file or a directory (folder) and the elements leading to it are directories. However, they also have both surface and fundamental differences. Here is a brief review of each, for comparison purposes. Unix pathname elements are separated by a slash, /. An absolute pathname always starts with a /. A relative pathname always starts with the name of a directory (except, of course, in the minimal case of naming a single file). The current directory is specified by . ("dot"); the parent directory is specified by .. ("dot dot"). The file tree can be traversed upwards by adding additional parents, .., always separating path elements by /.
Mac OS pathname elements, in contrast, are separated by a colon, :. An absolute pathname always starts with the name of a volume. A relative pathname starts with a colon, :, followed by the name of either a folder or a file (except in the minimal case of naming a single file, in which case the colon is optional). The current directory is specified by :; the parent directory by ::. The file tree can be traversed upwards by adding additional parents, :, but no additional separators.
SummaryAs you can see, there are certainly differences between "regular" Perl and MacPerl. However, we hope you've come to realize that the differences may not be as vast as you might have thought. For the most part, all functions are implemented, if those functions would have meaning under the Mac OS. You may have to do a little work if you want to be sure your code is portable to other systems. And you may have to do some extra work to port code that was written for other systems. But you may be pleasantly surprised at how easily Perl scripts can be made to run on either Mac OS or Unix, if you exercise a little thought and care when writing them. ReferencesMacPerl, currently version 5.2.0r4, is available from the CPAN in the directory /ports/mac. MacPerl: Power and Ease (Vicki Brown and Chris Nandor, 1998, ISBN 1-881957-32-2) is published by Prime Time Freeware. Fetch is available from Dartmouth College. Anarchie is available from Stairways Software. ToolServer and MPW are available from Apple Computer's MPW ToolZone.
Much of the information above was previously published as part of
Chapter 9, "Odd Corners", in MacPerl: Power and Ease by
Vicki Brown and Chris Nandor (publ. 1998, Prime Time Freeware).
|
|||||||||||||||||||||||||||||||||||||||||||||||||
![]() |
| ![]() |
||||||||||||||||||||||||||||||||||||||||||||||||
Copyright to all articles belong to their respective authors. Everything else © 1999 PerlMonth