oreilly.comSafari Books Online.Conferences.


AddThis Social Bookmark Button

Using Perl to Manage Plist Files

by James Reynolds

A year and a half ago, I wrote an article on scripting Mac OS X. One of the most common feedback questions was how to manage complex Plist files with scripts. The defaults command, which is often used to manage simple values in Plist files, does not easily manage the nested arrays or dictionaries that are present in most Plist files.

Recently, I learned about the PerlObjCBridge that was included in Mac OS X 10.3. It was one of those new OS features that got so little attention, that it wasn't until Mac OS X 10.4 came out that I became aware of it. It allows you to use Cocoa code in Perl scripts. Cocoa can easily manage Plist files. When I first heard about the PerlObjCBridge, I was ecstatic; specifically, because I can now manage Plist files with my scripts.

As I learned how to use the PerlObjCBridge, I also learned about Camelbones. Camelbones is another Perl-to-Cocoa bridge. PerlObjCBridge and Camelbones are very similar; not just in what they do, but in usage and syntax as well. The PerlObjCBridge ships with Mac OS X 10.3 and above. However, it can not be used to create a GUI application. You can create GUI applications with Camelbones. I will focus on the PerlObjCBridge because it is included with the OS so you do not need to install anything, and because we do not need a GUI to manage Plist files.

This topic will be covered by two articles. In the first, I will compare a Cocoa example with a Perl version and show a few differences between Cocoa and Perl notation. Then I'll provide a Cocoa tutorial, including how to create objects and a little about pointers and references. Finally, I'll jump into Plist file management by loading the computer network preferences from a Plist file and reading values, even nested values.

Related Reading

Learning Perl
By Randal L. Schwartz, Tom Phoenix, brian d foy

The second article will start by showing how to change values, such as the computer's name, and how to save the changes back to disk. Then it will cover scanning a Plist file. For an example, I'll get a dump of the NetInfo database and look at all the users in the database. In essence, this example will show how to convert Cocoa arrays and dictionaries to Perl arrays and hashes. The second article will close by creating a Plist file from scratch. For an example, I'll create a Plist file of an Xgrid batch submission. The core of this last example will show how to convert from Perl arrays and hashes to Cocoa arrays and dictionaries.

In writing these articles, I assume you know a little Perl, so I wont explain things like variables, loops, how to create and execute scripts, or most scripting jargon. If you need an introduction to any of that, I recommend you read an introduction to scripting (shameless plug). If you are unfamiliar with Perl hashes and arrays, you should brush up, because they are important when managing Plist files.

As I was pulling all of this together, I had to make some assumptions. I decided that knowing Cocoa wouldn't be a prerequisite for this series. If you're Cocoa-comfortable, you might want to skip the sections subtitled "Object-Oriented for Dummies". If you do not know Cocoa, I will cover the very minimum; enough for you to understand the code in the article, but certainly not enough for you to start writing your own Cocoa code.

Cocoa and Perl

Here is a simple "Hello World" program written in Cocoa.

#import <foundation/Foundation.h>

int main (int argc, const char * argv[]) {
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];

    // These are the 4 lines we care about:
    NSString *s1 = [NSString stringWithCString:"Hello "];
    NSString *s2 = [[NSString alloc] initWithCString:"World"];
    NSString *s3 = [s1 stringByAppendingString:s2];
    printf ("%s\n", [s3 UTF8String]);

    [s2 release];

    [pool release];
    return 0;

Here is a Perl script that calls the same Cocoa functions or methods using the PerlObjCBridge.


use Foundation;

# These are the lines we care about:These
$s1 = NSString->stringWithCString_("Hello ");
$s2 = NSString->alloc()->initWithCString_("World");
$s3 = $s1->stringByAppendingString_($s2);
printf "%s\n", $s3->UTF8String();


Pages: 1, 2, 3, 4, 5

Next Pagearrow