Stories
Slash Boxes
Comments
NOTE: use Perl; is on undef hiatus. You can read content, but you can't post it. More info will be forthcoming forthcomingly.

All the Perl that's Practical to Extract and Report

use Perl Log In

Log In

[ Create a new account ]

gnat (29)

gnat
  (email not shown publicly)

Journal of gnat (29)

Wednesday November 19, 2003
02:05 AM

ApacheCon: reinvigorating

[ #15858 ]
I'd forgotten how much fun it is to code. Somehow, hanging around the PHP folks, as they sit around and casually program while chatting, reawakens the dormant hacker in me. I don't know why, but the same thing happened last year.

So this evening, while those who had money were off seeing Zumanity (Cirque du Soleil, n3kk1d), I started hacking again. I have about 1/3 of a POP3 server written in Perl. I got sidetracked halfway through and started playing with Apple's AddressBook API in C.

What I learned is that I really like Perl. Perl hides a lot of stuff that you really shouldn't have to think about. Like strings, for example. I can't believe how amazingly painful it is to just print a list of the names of people in your address book. This is, I suspect, a byproduct of using the CoreFoundation classes for strings, but I'm forced to because that's what AddressBook does.

Check it out:

  for (i=0; i < count; i++) {
    ABPersonRef thisPerson;
    CFStringRef firstNameCF, lastNameCF;
    CFDataRef   firstNameDR, lastNameDR;
    CFIndex     firstNameLength, lastNameLength;

    thisPerson = (ABPersonRef) CFArrayGetValueAtIndex(array, i);
    firstNameCF = ABRecordCopyValue(thisPerson, kABFirstNameProperty);
    if (firstNameCF) {
      firstNameLength = CFStringGetLength(firstNameCF);
      firstNameDR = CFStringCreateExternalRepresentation(NULL, firstNameCF, CFStringGetSystemEncoding(), '?');
      printf("%.*s ",
             (int)CFDataGetLength(firstNameDR), CFDataGetBytePtr(firstNameDR));
      CFRelease(firstNameDR);
      CFRelease(firstNameCF);
    }

    lastNameCF = ABRecordCopyValue(thisPerson, kABLastNameProperty);
    if (lastNameCF) {
      lastNameLength = CFStringGetLength(lastNameCF);
      lastNameDR = CFStringCreateExternalRepresentation(NULL, lastNameCF, CFStringGetSystemEncoding(), '?');
      printf("%.*s",
             (int)CFDataGetLength(lastNameDR), CFDataGetBytePtr(lastNameDR));
      CFRelease(lastNameDR);
      CFRelease(lastNameCF);
    }
    printf("\n");
  }

All that, just to do the equivalent of:

  foreach my $thisPerson (@array) {
    $firstName = $thisPerson->{firstName} || "";
    $lastName = $thisPerson->{lastName} || "";
    print "$firstName $lastName\n";
  }

How can anyone program in this ridiculous quagmire of strings, C strings, data references, ... ? I seriously hope there's an easier way that I'm missing.

--Nat

The Fine Print: The following comments are owned by whoever posted them. We are not responsible for them in any way.
 Full
 Abbreviated
 Hidden
More | Login | Reply
Loading... please wait.
  • by ziggy (25) on 2003.11.19 18:33 (#25906) Journal
    Why would you ever code against the CF* APIs? It's for masochists, foot-draggers, and hackers working at a low level. For anything serious, you really should be using the ObjC frameworks. If you're into that much pain, go buy the new Brittany album instead.

    Here's the same code using the AddressBook framework. Note how it's almost Perl-like in a perverse kind of way:

    #import <Foundation/Foundation.h>
    #import <AddressBook/AddressBook.h>

    void dump_ab_people() {
        NSArray *people = [[ABAddressBook sharedAddressBook] people];
        NSEnumerator *iter = [people objectEnumerator];
        ABPerson *person;

        while (person = [iter nextObject]) {
            NSLog(@"%@ %@\n",[person valueForProperty:kABFirstNameProperty],
                             [person valueForProperty:kABLastNameProperty]);
        }
    }

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

        // insert code here...
        dump_ab_people();

        [pool release];
        return 0;
    }
    Not as easy as Perl, but not as fugly as the CF* version. Throw this into a "Foundation Tool", add the framework, and you're good to go.
    • I was thinking about turning it into a Perl XS module, and I was trying to start with what I know (C) instead of taking the risk of discovering problems with XS and Objective C.

      So the CoreFoundation is just a cunning plot to make Objective C seem attractive? Got it. :-)

      --Nat

      • No, CoreFoundation does have its uses. IBM's SWT is a high level abstraction of a modern GUI. It translates to CoreFoundation on the MacOSX side and the Win32 C API on the Windows side. But apps like that are rare.
    • I was looking at your very nice example, can you guide me on getting started building?

      I have followed some guidelines from the 'OS X for Unix Geeks' and ADC documentation, but without any luck.

      I am on 10.3 and I have the developer tools installed.
      • If you've got the developer tools installed, take a spin around /Developer/Documentation. Apple has lots of reference documentation and tutorials to get you started. They really want to help you write Cocoa apps. Most of the topics in the references contain overviews and introductions to get you started.

        You may want to get a copy of one of the Cocoa programming books from O'Reilly. I've got Simson Garfinkel's (mostly because he wrote the NeXTSTEP version, from which the O'Reilly title is derived). I

  • Is this from the ground up, or is it leveraging any of the previous perl pop3 server attempts?? I hope your little coding hack takes off, frankly I would love to see a basic pop3 & imap server implementation in perl. Extending a basic framework like that to create dynamic virtual folders etc, could be wicked cool. -- John Cavanaugh
    • It's from the ground up, just proving to myself that it can be done without a zillion CPAN modules. I was excited about dynamic virtual folders, but when Casey asked me what I'd use it for, I struggled to come up with much more than "uh, turn your mail client into an RSS aggregator?". Either I'm not thinking hard enough about what I could do with it, or I thought the idea was cooler than it actually is ...

      --Nat

      • Nat, why don't you write the first practical mod_perl 2.0 protocol module. It should be a trivial thing once you have the basic code working by itself. On my mod_perl 2.0 I keep on saying that you can now implement protocols in mod_perl, like imap, pop3, etc. But it'd be much better if I could say. Nat implemented an imap protocol for mod_perl 2.0 in N hours, here is the URL.
        --

        Stas Bekman [stason.org] of

      • like qpsmtpd [develooper.com], i think a pop3/imap server written in perl would simply be accessible for hacking and experimentation.

        mandrill [trainedmonkey.com] was my start at writing something like an imap server. (not really a true server, but something meant to be run using mutt's tunnel feature.)

        but the imap spec bites. you really don't want to write an imap server.