|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
179
|
|
Chapter 13:
|
|
|
|
|
The Toolbox Modules
|
|
Everybody knows a little bit of something.
|
|
- King's X, Gretchen Goes to Nebraska
|
|
The previous chapter covered the Mac-specific built-in functions that are
contained in the MacPerlpackage. This chapter covers a set of MacPerl-
specific modules, known as the Toolbox Modules. These modules cover all
manner of Mac OS programming needs, from getting file information to proc-
ess control, interapplication communication, graphics, speech recognition,
QuickTime movies, and the Earth's revolution around the Sun.1
|
|
Note: Some functionality in the Perl core modules (e.g., File::Copy) is
implemented via the Toolbox Modules. These modules are not installed
by default on 68K Macintoshes. If you use a 68K Macintosh, make sure
that either CFM-68K MacPerl or BigMacPerl is installed.
|
|
There is a lot of stuff here. We suggest that you start by skimming through
the chapter. After you have become familiar with the general purposes of
the modules, you can go back and try one of them out. In short, you don't need
to understand it all; you only need to understand the parts that you use.
|
|
One more note: these modules have been used to varying degrees and are at
various levels of maturity. It is possible that some functions will not work
as expected; if something does not work properly, report it to the MacPerl
mailing list. Also, though the interfaces seem to be stable, they are subject
to change. As always, let the programmer beware.
|
|
|
|
1
Assuming that the Earth does, indeed, revolve around the Sun.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
The toolbox modulesaccess the Mac OS Toolbox,2a set of instructions for
controlling various Mac OS functions. Mac OS has thousands of toolbox
calls; these modules attempt to provide MacPerl with a useful subset.
|
|
Inside Macintoshprovides useful information on the toolbox calls; the doc-
umentation that comes with each module provides detailed information on
the module and any module-specific issues that may be involved. The Mac-
Perl folder contains some examples of module use, in the folder :ext:Mac:.
|
|
Note: Inside Macintosh(available from Apple Computer) details the
Macintosh system software. The books are freely available on the
Internet in various electronic forms, and the most important books to
MacPerl programming are on the MacPerl CD-ROM. In some cases, the
cross reference and other books could be out of date. Check the Apple
site periodically for updates.
|
|
This chapter is an introduction and supplement to, not a replacement for,
the detailed documentation listed above. As the descriptions for the tool-
box modules state:
|
|
Access to Inside Macintoshis essential for proper use of these functions.
Explanations of terms, processes and procedures are provided there.
Any attempt to use these functions without guidance can cause severe
errors in your machine, including corruption of data. You have been
warned.
|
|
With luck, we will give enough guidance to allow you to use some modules
successfully. Nonetheless, you will be directly accessing Mac OS toolbox
calls through MacPerl, and you are running a risk if you do not know what
you are doing. The authors of this book will notbe held responsible if you
unknowingly alter the Earth's orbit.
|
|
The good news is that if you know Mac OS programming, the documentation
included here and with the toolbox modules is sufficient to get you going. If
not, you should read the relevant sections of Inside Macintoshanyway.
|
|
Inside Macintoshhas a cross reference which includes every toolbox routine
name. If you will be using the toolbox modules extensively, spend some time
familiarizing yourself with the cross references and general layout of the
books. This will help you to find what you need quickly and painlessly.
|
|
|
|
2
Also called the Mac OS API
(Application Program Interface).
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Using The Toolbox Modules
|
|
The MacPerl toolbox functions have the same names and take their input
arguments in basically the same order as their Mac OS toolbox counterparts.
Output from the functions is always returned as either a single value or as a
list (if multiple arguments are returned). If an error occurs, the function
returns undeffor scalar context or ()for list context; the error code is
available in the special variable $^E.3
|
|
Complex data structures are put into objects(as discussed in chapter 11). The
data fields are made available through methods which normally return
the value of the field when called without an argument, changing the
value of the field when called with an argument:
|
|
$object = someFunction();
$data= $object->dataField(); # get data
$object->dataField('somedata'); # set data
|
|
Functions and constants are exported into the namespace of the package
that is current when the module is called with use.4Constants are repre-
sented as functions that return a constant value,5so they normally should be
followed by parentheses (i.e., $Data{someConstant()}). Other data
structures (e.g., hashes) may be exported, as well.6
|
|
Mac::AppleEvents, Mac::OSA
|
|
The Mac::AppleEventsand Mac::OSAmodules, along with MacPerl::
DoAppleScript(), are the primary means of doing interapplication com-
municationwith MacPerl (that is, communicating with other programs on
your Macintosh).
|
|
This is such a rich and important topic that we have given it given it a
whole chapter, AppleScript, Etc.If you have not used any of the toolbox
modules, however, you might want to read further here before moving on.
|
|
|
|
3$^Eis similar to $!(which contains the current error), but is for platform-specific
errors. MacPerl uses $^Eonly for its toolbox modules.
4Because they are explicitly exported, the toolbox functions and constants do not need
to be prefixed with Mac::before each use. Note the examples throughout this chapter.
5Perl has constants, but they are currently implemented as subroutines.
6Also see Toolbox.podin the MacPerl distribution, available under the Help menu
under Macintosh Toolbox Modules/ Overview.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Mac::Files
|
|
The Mac::Filesmodule is not, ironically, used for dealing with files, per
se. Instead, it contains functions for moving, renaming, creating, finding,
modifying, and getting information about files and folders on your machine.
|
|
FSpCreate(FILE, CREATOR, TYPE)creates a file with a specified cre-
ator and type. The Perl open()function creates files, but with MacPerl's
default creator and type. You can also use MacPerl::SetFileInfo()to
change the creator and type, as discussed in the previous chapter.
|
|
In the course of your toolbox usage - especially in Apple Event program-
ming - you might need access to an alias handle for a file. NewAlias-
Minimal(FILE)returns the needed alias handle.
|
|
You can also use toolbox calls to lock files. FSpSetFLock(FILE)and FSp-
RstLock(FILE)set and reset (release) a lock on a specified FILE. This is
notthe same as Perl's flock()function, which is not implemented in Mac-
Perl, but it is similar.
|
|
Locking a file with FSpSetFLockmakes all new access paths to that file
read-only. If a file is already opened by an application when the file is
locked, that application can write to the file as before. For this reason, the
first open()below succeeds, while the second open()fails.
|
|
#!perl -w
use Mac::Files;
my($f) = 'myfile';
|
|
open(F, ">>$f") or warn($!);
FSpSetFLock($f);
print F "some text\n";
close(F);
|
|
open(F, ">>$f") or warn($!);
FSpRstFLock($f);
|
|
Mac::Filesalso has a function for finding the path to a particular folder
(usually on the startup volume). FindFolder()is passed a volume and a
type to look for. (Hint: to specify the startup volume, pass the parameter
kOnSystemDisk().) As the second argument, pass a constantspecifying
the type of the item to be found. Acceptable constants are:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
kAppleMenuFolderType
kControlPanelFolderType
kDesktopFolderType
kExtensionFolderType
kFontsFolderType
kPreferencesFolderType
|
kShutdownFolderType
kStartupFolderType
kSystemFolderType
kTemporaryFolderType
kTrashFolderType
|
|
Here is a portable way to open a preference file (e.g., "myprefs") on any
Macintosh, regardless of the name of the startup volume or system folder:
|
|
#!perl -w
use Mac::Files;
my($prefsDir, $mpp);
|
|
$prefsDir = FindFolder(kOnSystemDisk(),
kPreferencesFolderType()
);
$mpp = "$prefsDir:MacPerl 5 Preferences";
|
|
Mac::Filesalso provides a way of getting information about files, though
it can be a bit cryptic to use. FSpGetCatInfo(FILE [, INDEX])and
FSpSetCatInfo(FILE, INFO)deal with objects in the CatInfoclass.
See Inside Macintoshfor in-depth information, but here is an overview.
|
|
After passing a file to FSpGetCatInfo()and retrieving an object of the
class CatInfo, you can call various methods that will return either scalar
values or objects of other classes.
|
|
#!perl -w
use Mac::Files;
my($file, $fileCat, $fileInfo);
|
|
$file= 'HD:Desktop Folder:Untitled';
$fileCat= FSpGetCatInfo($file)or die($^E);
$fileInfo = $fileCat->ioFlFndrInfo() or die($^E);
print$fileCat->ioNamePtr(), "\n";
print $fileInfo->fdCreator(), "\n";
|
|
$fileInfo->fdCreator('R*ch')or die($^E);
print $fileInfo->fdCreator(), "\n";
|
|
$fileCat->ioFlFndrInfo($fileInfo)or die($^E);
FSpSetCatInfo($file, $fileCat)or die($^E);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Displays:
|
|
Untitled
McPL
R*ch
|
|
In this code, ioNamePtr()returns the file name and ioFlFndrInfo()
returns an object (belonging to class FInfo) through which more file
information can be retrieved. Note that, after we change the creator in the
FInfoobject to R*ch, we need to copy it back to the CatInfoobject, then
set it with FSpSetCatInfo().
|
|
As we already know, we can find out this same information with other rou-
tines. But sometimes, as with the Mac::StandardFilemodule, we will
have to use these methods to get our file information. Also, if you need some
slightly more obscure information about a file, such as flags, these methods
are the ones to use.7
|
|
Mac::StandardFile
|
|
The Mac OS standard file dialogs are found in the Mac::StandardFile
module. The four basic functions - standard open and save dialogs, custom
open and save dialogs - are all that are needed to do the majority of GUI
file system interaction that programs need to do.
|
|
Note that these functions do not actually open or save files; they only let
the user interact with a GUI to tell your program which file he wants to
access. Your program must do the work of saving and opening the file.
|
|
Let's start with the basic StandardGetFile(FILEFILTER, TYPELIST)
function. When called, it opens a standard dialog box in the directory speci-
fied in the Mac OS General Controls Control Panel. It will only show files
that match file types specified in TYPELIST. (If TYPELISTis null, all files
will be shown.)
|
|
The function returns a StandardFileReplyobject. This object has a set of
methods that return information about the file. The sfType()method, for
example, returns the file type of the selected file. sfFile()contains the
|
|
|
|
7Perl's -s file test gives the size of a file's data fork only. To get the full size of a file,
including the resource fork, get the CatInfoobject for the file; the size is $fileCat->
ioFlLgLen() + $fileCat->ioFlRLgLen().
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
full file name. sfGood()is a Boolean value that is true if a file was selec-
ted, false if the user cancelled the operation.
|
|
This example looks for TEXTand clpt(clipping) files; note that the types
are concatenated ('TEXTclpt') without intervening spaces.
|
|
#!perl -w
use Mac::StandardFile;
my($file);
|
|
$file = StandardGetFile(0, 'TEXTclpt');
if ($file->sfGood()) {
printf("You chose %s, of type %s.\n",
$file->sfFile(), $file->sfType()
);
} else {
print "You cancelled the operation.\n";
}
|
|
Displays:
|
|
You chose HD:Desktop Folder:Hello.pl, of type TEXT.
|
|
When the file is selected, an object is passed back. We check to see if the
user actually selected a file (with sfGood()), and if so, print out informa-
tion about that file. Now that we have the name in $file->sfFile(),
we can open the file with open()and do what we want with it.
|
|
The FILEFILTERparameter allows you to filter candidate files. If you
pass a null value, no filtering takes place. You can pass a reference to a
function, however, and filter files in any desired manner.
|
|
Your filter function will be passed a CatInfoobject (from the Mac::Files
module) for each file that the dialog box encounters. Most filters have to do
with file name, file type, or creator type.
|
|
The filter function checks each file that gets passed to it. In the example
below, we check the file name to see if it ends in .pl, then check to make sure
this is a MacPerl text file. We can let the filter check the file type;
however, in practice, it is faster to let StandardGetFile()take care of
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
that. The filter function can only filter files that StandardGetFile()
passes to it.8
|
|
Note that the FILEFILTERreturns truefor a file that should not be shown,
and falsefor a file that should be shown. We are checking for characteris-
tics of files that we dowant to show, so we negate the return value.
|
|
#!perl -w
use Mac::StandardFile;
use Mac::Files;
my($file);
|
|
$file = StandardGetFile(\&myFilter, 0);
if ($file->sfGood()) {
printf("You chose %s\n", $file->sfFile());
} else {
print "You cancelled operation\n";
}
|
|
sub myFilter {
my($fileCat, $fileInfo);
|
|
$fileCat= $_[0];
$fileInfo = $fileCat->ioFlFndrInfo() or die($^E);
return !(
$fileInfo->fdCreator() eq 'McPL' &&
$fileInfo->fdType()eq 'TEXT' &&
$fileCat->ioNamePtr()=~ /\.pl$/
);
}
|
|
Displays:
|
|
You chose HD:Desktop Folder:Hello.pl.
|
|
Our call to StandardGetFile(0, 0)specifies no filter function or file
types, so all files are shown.
|
|
Mac::StandardFilealso provides a StandardPutFile(PROMPT,
DEFAULTNAME)function. This puts up a Save Asdialog with a message
|
|
|
|
8The Mac OS Easy OpenControl Panel can cause problems with recognizing the file
types you specify in TYPELIST. Checking the file type in the filter will take care of this.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
prompt for the user and an optional default name for the file. This time,
sfReplacing()returns true if this file is replacing another file, false
otherwise. If the file already exists, the script below double-checks and
asks the user if he really wants to erase the existing file.
|
|
#!perl -w
use Mac::StandardFile;
my($answer, $file);
|
|
$file = StandardPutFile('Filename:', 'myfile.txt');
if ($file->sfGood()) {
$answer = (
MacPerl::Answer('Erase existing file?',
'No', 'OK')
) if ($file->sfReplacing());
if ($answer) {
printf("%s exists; cancelled.\n",
$file->sfFile());
exit();
}
open(FILE, '>' . $file->sfFile()) or die($!);
print FILE "Here is some text.\n";
close(FILE);
printf("File created: %s\n", $file->sfFile());
} else {
print "User cancelled operation.\n";
}
|
|
If these dialog boxes are insufficient for your needs, feel free to create your
own. This will require an intimate understanding of dialog resources, how-
ever, and some extensive use of Inside Macintosh. See Chapter 14, GUI Tool-
box Modules, for some introductory material.
|
|
Here's a quick example, using a dialog resource that is already available in
the MacPerl application. The standard MacPerl Save As...dialog is in ID
192. We use the Mac::QuickDrawmodule and its Pointclass to position
the window (the given values center the dialog on the screen).
|
|
#!perl -w
use Mac::StandardFile;
use Mac::Files;
use Mac::QuickDraw;
my($file, $x);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
$x= new Point (-1, -1);
$file = CustomPutFile('Filename:', 'file.txt', 192,
$x);
if ($file->sfGood()) {
printf("File selected: %s\n", $file->sfFile());
} else {
print "User cancelled operation.\n";
}
|
|
Mac::MoreFiles
|
|
Mac::MoreFilesoffers several file and directory access routines that
complement the ones in Mac::Files.
|
|
FSpCreateMinimum(FILE)creates a file from a given path or filespec,
like FSpCreate(), but gives the file no creator or type. FSpShare(FILE)
and FSpUnshare(FILE)take a directory or volume filespec and turn file
sharing on or off for it. FSpDirectoryCopy(SRC, DEST, PREFLIGHT)
copies a directory to another location. (It does not rename the directory.)
|
|
#!perl -w
use Mac::MoreFiles;
my($dir)= 'HD:MacPerl :macscripts';
my($dest) = 'HD:Desktop Folder';
|
|
FSpDirectoryCopy($dir, $dest, 0) or die($^E);
|
|
FSpDTGetAPPL(VOLUME, CREATOR)returns the full path to an applica-
tion with the specified creator ID. The time it takes may vary, based on
the condition of your desktop database and the size of your filesystem.
|
|
Because you might not know the application's volume, Mac::MoreFiles
exports a tied hash (using FSpDTGetAPPL()) called %Application.
Using an application ID as the key, the hash returns the path to the appli-
cation. The two printstatements below will display exactly the same
information, if your MacPerl application is on your startup volume:
|
|
use Mac::MoreFiles;
print FSpDTGetAPPL(0, 'McPL');
print $Application{'McPL'};
|
|
On most Mac OS filesystems, the Finder gives access to file comments by
means of the Get Infoitem in the Filemenu. FSpDTSetComment(SPEC,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
COMMENT)sets a filespec comment to a text string. FSpDTGetComment
(SPEC)returns the comment; FSpDTCopyComment(SRCSPEC, DSTSPEC)
copies a comment from one file to another.
|
|
Here we set the comment for the MacPerl application, then copy its com-
ment to another file:
|
|
#!perl -w
use Mac::MoreFiles;
my($file1, $file2);
|
|
$file1 = MacPerl::MakeFSSpec($Application{'McPL'});
$file2 = MacPerl::MakeFSSpec('HD:Files:file.txt');
FSpDTSetComment($file1, 'Power and Ease');
FSpDTCopyComment($file1, $file2);
print FSpDTGetComment($file2), "\n";
|
|
Displays:
|
|
Power and Ease
|
|
FSpDTGetAPPL()and %Applicationreturn paths, but the comment-
handling functions need filespecs. So, we use MacPerl::MakeFSSpec()to
convert the paths above into filespecs.
|
|
Mac::Processes
|
|
A processis a program that is running on a computer. This might be, among
other things, an application or a desk accessory.
|
|
Mac::Processesexports a hash called %Process. Each key of the hash
is a process number. The values are objects that allow access to methods for
getting more information about a specific process, including its name, type,
and more. By iterating over the hash, you can get information on all active
processes. The script below prints a sorted list of application names:
|
|
#!perl -w
use Mac::Processes;
my($psn);
|
|
foreach $psn (keys(%Process)) {
push(@names, $Process{$psn}->processName());
}
print map("$_\n", sort(@names));
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Displays:
|
|
BBEdit 4.5
File Sharing Extension
Finder
MacPerl
Shuck
|
|
The objects in %Processhave access to the following methods:
|
|
processActiveTime
processAppSpec
processLaunchDate
processLauncher
processLocation
processMode
|
processName
processNumber
processSignature
processSize
processType
|
|
The %Processhash is implemented throughthe GetNextProcess(PSN)
and GetProcessInformation(PSN)functions.
|
|
GetNextProcess()returns the process whose number follows PSN(even if
PSNis not a valid process number). If PSNis 0, the function returns the low-
est-numbered process. GetProcessInformation()retrieves information
about a given process, returning the process object described above.
|
|
Two other functions return process numbers. GetCurrentProcess()returns
the number of the process that is using the CPU. Because of the way Mac-
Perl works, this will always be the process number of MacPerl. GetFront-
Process()returns the number of the process that is "in front" on the screen.
SetFrontProcess(PSN)moves the specified process to the front.
|
|
Mac::Processesalso gives MacPerl scripts the ability to launch other
applications. It isn't as simple as it is in Unix, where an open(), exec(),
or similar call can open a process.9Instead, you have to use the Launch-
Application()function.
|
|
The implementation of this function changed in MacPerl 5.1.4r4, so older
code might not work. First, we call new()in the LaunchParampackage.
This constructor accepts a hash of parameters describing the process to be
launched. See Inside Macintoshfor complete details.
|
|
|
|
9If you have MPW and ToolServer, you can call an external program from a MacPerl
program with system(), however.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
The new()constructor requires the launchAppSpecparameter, which is
the filespec of the application to launch. We can get the filespec by using
the %Applicationhash from Mac::MoreFiles. We also want to set the
launchControlFlagsparameter to launchContinue(). Without this,
MacPerl would quit after launching the application.
|
|
#!perl -w
use Mac::MoreFiles;
use Mac::Processes;
my($app);
|
|
$app = new LaunchParam(
'launchControlFlags' => launchContinue(),
'launchAppSpec'=> $Application{'R*ch'}
) or die($^E);
LaunchApplication($app) or die($^E);
|
|
Mac::Gestalt
|
|
Mac::Gestaltreturns information about the operating environment. It
exports the tied hash%Gestalt, which returns codes for a (large!) set of
constants. Inside Macintoshgives a complete list of the constants and their
meanings. Here is an example to get you started:
|
|
#!perl -w
use Mac::Gestalt;
my($arch, %archs, $mac);
|
|
$arch= $Gestalt{gestaltSysArchitecture()};
%archs = (gestaltPowerPC() => 'a PPC',
gestalt68k()=> 'a 68k');
$mac= (defined($archs{$arch}) ?
$archs{$arch}: 'an unknown');
MacPerl::Answer('You are using a Macintosh with ' .
"$mac architecture.");
|
|
To print the complete list of constants, try:
...
my($key);
|
|
foreach $key (sort(keys(%Mac::Gestalt::))) {
print "$key\n" if ($key =~ /^gestalt/);
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Mac::Types
|
|
There are basically two functions in this module, MacPack(CODE, DATA)
and MacUnpack(CODE, DATA). MacPack()is similar to (and implement-
ed via) Perl's pack()function. It puts a value (or a list of values) into the
specified Mac OS data type.
|
|
For instance, with Apple Events, every parameter must be of a certain type
(e.g., keyword, TEXT). To make sure that you are passing the correct type,
you can filter the value through MacPack()first. And, when you receive
values, you can filter them through MacUnpack(). Here is an example of
packing and unpacking a short integer:
|
|
#!perl -w
use Mac::Types;
my($x);
|
|
$x = MacPack('shor', 9874.70);
print MacUnpack('shor', $x), "\n";
|
|
Displays:
|
|
9874
|
|
Mac::Typescan pack and unpack many different data types:
|
|
'bool'A boolean (true/false) value
'doub'A double-precision floating-point number
'enum'An enumerated type
'fss 'A file specification record
'keyw'A 4-byte ("keyword") string
'long'A long integer
'magn'An unsigned long integer ("magnitude")
'qdrt'A QuickDraw Rect
'shor'A short integer
'sing'A single-precision floating-point number
'STR 'A Pascal-style string
'STR#'A string list
'TEXT'text
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Mac::Memory
|
|
Mac::Memoryprovides an interface to the Mac OS memory manager and
access to special data manipulation in memory.
|
|
In general, Perl programmers do not need to worry about memory. Perl has no
memory limitations aside from those imposed by your system and it auto-
matically adjusts allocated memory for data structures as needed. Howev-
er, Mac OS programs are assigned a certain amount of memory in which to
work. If you are dealing with enough data, you could easily use up all of
MacPerl's allocated memory.10
|
|
The following script snippet shows the current amount of free space that is
available in the MacPerl application. It can be useful for identifying mem-
ory leaks, which MacPerl is prone to due to occasional bugs in the Perl core
and the nature of the toolbox modules, which sometimes require manual
deallocation of memory.
|
|
The general concept is that the toolbox module calls in MacPerl do not auto-
matically dispose of memory that a C programmer would dispose of manu-
ally. We'll see more of this in Chapter 18, AppleScript, Etc.
|
|
FreeMem()returns the amount of free memory that is available in the
application. MaxMem()compacts and purges the current memory zone,
returning an array of two values: the amount of memory that is available
and the amount by which the memory can grow.11
|
|
#!perl -w
use Mac::Memory;
|
|
printf("Free Memory: %0.2f MB\n",
mbytes(FreeMem()));
printf("MaxMemory: %0.2f MB\n",
mbytes((MaxMem())[0]));
|
|
sub mbytes { $_[0] / (1024**2) }
|
|
|
|
10You can give any application (including MacPerl) more memory by selecting it in the
Finder, choosing Get Infofrom the Filemenu, and changing the value of Preferred
Size. Note that this can only be done when the application is not running.
11The syntax around MaxMem()puts the function into a reference to an anonymous
array and pulls out the first value.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Displays:
|
|
Free Memory: 6.37 MB
MaxMemory: 6.34 MB
|
|
Mac::Memorycan also be used as a way to manipulate data in memory. We
will see an example of this below, in Mac::Resources, where the data of
a resource is stored in an object from the Handleclass in Mac::Memory.
|
|
Mac::Resources
|
|
Mac::Resourcesallows you to access the Mac OS Resource Manager. Nor-
mally, this will involve searching through, reading, and editing existing
resources, as well as creating new resources. The following example demon-
strates some basic routines.
|
|
This example droplet takes a MacPerl file saved as a CGI script and sets
the default number of minutes it stays open (5) to any value from 1 to 127 (a
value of 0 keeps the CGI script open indefinitely).
|
|
We first use Mac::Typesto pack the number into the correct format. The
script then opens each file that is dropped on it as a resource file, using
OpenResFile(FILE). This sets the current resource file, which is returned
at any time by CurResFile(). We ask for the timeresource ID 128; if it
exists, an object of the Handleclass from Mac::Memoryis returned. We set
its value with the set(OFFSET, LENGTH, DATA)method.
|
|
Now the changed resource is in memory, but needs to be saved back to disk.
We mark the resource as changed, using ChangedResource(HANDLE), up-
date the file, then close it.
|
|
We have to release the memory, because while MacPerl handles memory
allocation for us, the toolbox does not. So we call ReleaseResource()
when we are done with the resource handle.12
|
|
#!perl -w
use Mac::Resources;
use Mac::Memory;
use Mac::Types;
my($min, $pmin, $file, $res);
|
|
|
|
12This droplet, with a GUI interface, is stored on the CD-ROM as setCGImins.drop.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
$min= 15;# any value 1..127, or 0
$pmin = substr(MacPack('long', $min), 3, 1);
foreach $file (@ARGV) {
OpenResFile($file)or die($^E);
$res = Get1Resource('time', 128);
if ($res) {
$res->set(0, 1, $pmin)or die($^E);
ChangedResource($res)or die($^E);
UpdateResFile(CurResFile())or die($^E);
ReleaseResource($res)or die($^E);
} else { warn($^E) }
CloseResFile(CurResFile());
}
|
|
Note that we can getthe current value of the Handleobject with the get()
method, and that there are several other functions for getting and updating
resources. All of these are thoroughly documented in Inside Macintoshand
the Mac::Resourcesdocumentation.
|
|
Mac::InternetConfig
|
|
A freeware configuration system called Internet Confighas surfaced because
of the need to keep Internet-related preferences in a central location. It is so
handy that it has become a standard on Mac OS.
|
|
InternetConfigprovides a basic interface to the preferences. The module
is normally used to retrieve and set the values stored by Internet Config. It
exports a tied hash for this purpose, named %InternetConfig. A list of
all possible constants is given in the documentation, but this script displays
of the more some useful ones:
|
|
#!perl
use Mac::InternetConfig;
|
|
print $InternetConfig{kICRealName()},"\n";
print $InternetConfig{kICEmail()},"\n";
print $InternetConfig{kICWWWHomePage()}, "\n";
|
|
Displays:
|
|
Joe Smith
joe@company.com
http://www.company.com/
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
These values can also be set, using the same interface:
|
|
$InternetConfig{kICEmail()} = 'jsmith@company.com';
|
|
ICLaunchURL(INST, HINT, DATA)is another useful Internet Config rou-
tine. The example below starts a connection to the Internet Config system,
using ICStart(), returning an instance.
|
|
The instance is configured, then used to launch a URL. In this case, the URL
we specify is the user's home page (already set in Internet Config). We then
close the link to the Internet Config system, using ICStop(INSTANCE).
|
|
#!perl -w
use Mac::InternetConfig;
my($icInst);
|
|
$icInst = ICStart();
ICGeneralFindConfigFile($icInst);
ICLaunchURL($icInst, 0,
$InternetConfig{kICWWWHomePage()});
ICStop($icInst);
|
|
Mac::InternetConfigalso (as of MacPerl 5.1.6r4) provides access to the
file mappings database in MacPerl. By passing the tied hash %Internet
ConfigMapa filename with an extension in the database, or a reference to
an array containing a file type and creator, you get back an object whose
methods return information about that entry in the IC database.
|
|
use Mac::InternetConfig;
$map1 = $InternetConfigMap{'myscript.pl'};
$map2 = $InternetConfigMap{['TEXT', 'R*ch']};
print $map1->file_type(),"\n";
print $map2->entry_name(), "\n";
|
|
Several methods are available to each object, as:
|
|
creator_app_nameextensionfile_type
entry_namefile_creatorMIME_type
|
|
If more than one entry fits the key passed to the hash, the hash returns the
first one it finds. You probably have a single entry for the .pl extension, but
you are likely to have multiple entries for TEXT/R*chif you use BBEdit.
|
Copyright © 1997-1998 by Prime Time Freeware. All Rights Reserved.