Mac Daemons in Perl | 2 | WebReference

Mac Daemons in Perl | 2

Mac Daemons in Perl

The Code

Hide('MacPerl', 1) or warn $^E;
my $channel = NewSpeechChannel($Voice{Victoria});

After loading in our modules, we immediately invoke Mac::Apps:Launch::Hide(), and tell it to force MacPerl into the background. Next, we create a new speech channel using Mac::Speech::NewSpeechChannel(). I'm not going into detail about what arguments NewSpeechChannel() takes, as I did that in my PerlMonth article. Still it should be clear that there is a hash Mac::Speech::%Voice, and I've passed a member of that hash $Voice{Victoria} to NewSpeechChannel(), and assigned the result to $channel.

    for (;;) {

Next we loop forever, or at least until someone brings the application to the front and aborts it by typing Cmd-. (Cmd is that funky clover-leaf key, and Cmd-. is pretty much standard for aborting a running process).

        my ( $year, $month, $day, $hour, $min, $sec) = 
reverse((localtime)[0 .. 5]);
        print "\n------------------------------\n";
        foreach my $psi (values %Process) {
       	printf("%s %s [%s bytes]\n",

This program doesn't log its output to a file (I could have done that, though), but just prints it to the MacPerl console. Each iteration gets a timestamp. Then for each member of the hash %Process (which is a hash of hashes, containing the _processInfoMap for each currently running process), we extract the application signature which is a unique four character code used to identify each application: MACS for the Finder, R*ch for BBEdit, and so forth. We then do the same for the application name (which is just what it says it is). Finally, we get the application size in bytes. Once again, I'm not giving ALL the details (a reading of Inside Macintosh is REALLY required!).

           my $process_name = $psi->processName();

In the previous bit of code, printf() handled the appropriate coercion for us. It's implicit when we say printf("%s") that we want the output coerced to a string. In the next step, however, we have to do the coercion ourselves. SpeakText() expects a string as its argument, so we assign $psi->processName() to $process_name.

           SpeakText($channel, "$process_name" );
                while (SpeechBusy()) {}

Whenever you make a call to SpeakText(), it needs to be followed by a call to while( SpeechBusy()){}. You could actually do something inside that loop while waiting for the speech to end, but I've chosen not to (keeping things simple).


Finally, we put the program to sleep for 15 seconds. During that time, MacPerl will indicate to the OS that it's not doing anything, and the OS will make that unused time available to the other processes. One last detail! If somehow, the code breaks out of its infinite loop (say someone does invoke Cmd-.), we need to dispose of the open speech channel.


Produced by Brian McNett
All Rights Reserved. Legal Notices.
Created: Feb 4, 2000
Revised: Feb 4, 2000