2011-04-03

gravatar.rb

I made myself a little command-line tool gravatar.rb today, which eats email addresses and outputs "gravatar-url email@address" lines, for all email addresses that has a customized gravatar created.

It's fun to run git log|gravatar for projects you've got checked out; here's yui3:


(People showing up more than once either have multiple email addresses registered with gravatar that they commit via or borrow someone else's picture. :-)

2011-03-29

Installing perl modules on Snow Leopard and Homebrew

Preamble: this post is a great read if you really want to have your Perl stuff in /usr/local, instead of in /Library/Perl, the MacOS X way. Otherwise, maybe not so much! (The error I had stumbled on, which made me think cpan didn't just work was, apparently, that I at some point had used sudo cpan, and gotten permissions on things out of whack. If cpan was a little bit more helpful, chances are I would have figured it out sooner -- but let's not toss a blog post that was fun to write and still has a few useful nuggets, despite being built on an otherwise shoddy fundament. :-)

First up: this isn't any more Homebrew specific than that I use the perl Apple ships with Snow Leopard (5.10 at this time of writing, for 10.6.7 - I'm on a Macbook Air myself), with all its built-in DTrace and MacOS integration goodness. Read that fine page for authoritative data; I neither am not pretend to be a perl savant.

Using the system perl is how Homebrew prefers it – unlike some other packaging systems I shall not mention here, as a service to other fine people trying to google for "perl mac snow leopard -this -that". Should you for any reason wish to mention those in comments on this post, you may call them "Funk" and "Warts" (or "MacWarts"). I may delete your comment if you don't. (Nothing personal; just sayin'. And you might as well not, anyway, I am unlikely to be able to help you.)

Anyway, so I want my perl modules installed in /usr/local, and I want them in my @INC when I run /usr/bin/perl and it's a shame that the system perl only looks in any of these, right?
/Library/Perl/Updates/5.10.0/darwin-thread-multi-2level
/Library/Perl/Updates/5.10.0
/System/Library/Perl/5.10.0/darwin-thread-multi-2level
/System/Library/Perl/5.10.0
/Library/Perl/5.10.0/darwin-thread-multi-2level
/Library/Perl/5.10.0
/Network/Library/Perl/5.10.0/darwin-thread-multi-2level
/Network/Library/Perl/5.10.0
/Network/Library/Perl
/System/Library/Perl/Extras/5.10.0/darwin-thread-multi-2level
/System/Library/Perl/Extras/5.10.0

Wrong! (I told you: read this fine manual written by knowledgeable people!) Still, a neat thing they describe is that the MacOS X perl installation will happily read /Library/Perl/5.10.0/AppendToPath and /Library/Perl/5.10.0/PrependToPath and append / prepend any directories they list (one line per path, normal unix style) to @INC. Or, of course, any other version than 5.10.0 – perl -v will tell you what you've got installed. So, as root, I appended /usr/local/lib/perl5/site_perl/ to my AppendToPath.

Next up, assuming you've already made a mess trying to install stuff with cpan (I had), you may want to do what I did, which is rm -rf ~/.cpan (which permanently nukes it; should you want to be able to undo that, you of course instead move it aside somewhere – you're solely responsible for your actions here, as always). Then run cpan. It'll ask you tons of questions you might not know the answer to any better than I did if you say no, or give slightly okay defaults if you say yes. Some frustrating experimentation later, I came down with this recipe, which worked for me; first yes it, and then when you get the prompt, type o conf. It'll probably look a bit like this, if the defaults remain about the same:
cpan[1]> o conf
$CPAN::Config options from '/Users/jhs/.cpan/CPAN/MyConfig.pm':
    commit             [Commit changes to disk]
    defaults           [Reload defaults from disk]
    help               [Short help about 'o conf' usage]
    init               [Interactive setting of all options]

    applypatch         []
    auto_commit        [0]
    build_cache        [100]
    build_dir          [/Users/jhs/.cpan/build]
    build_dir_reuse    [1]
    build_requires_install_policy [ask/yes]
    bzip2              [/usr/bin/bzip2]
    cache_metadata     [1]
    check_sigs         [0]
    colorize_debug     undef
    colorize_output    undef
    colorize_print     undef
    colorize_warn      undef
    commandnumber_in_prompt [1]
    commands_quote     undef
    cpan_home          [/Users/jhs/.cpan]
    curl               [/usr/bin/curl]
    dontload_hash      undef
    dontload_list      undef
    ftp                [/usr/bin/ftp]
    ftp_passive        [1]
    ftp_proxy          []
    getcwd             [cwd]
    gpg                []
    gzip               [/usr/bin/gzip]
    histfile           [/Users/jhs/.cpan/histfile]
    histsize           [100]
    http_proxy         []
    inactivity_timeout [0]
    index_expire       [1]
    inhibit_startup_message [0]
    keep_source_where  [/Users/jhs/.cpan/sources]
    load_module_verbosity [v]
    lynx               []
    make               [/usr/bin/make]
    make_arg           []
    make_install_arg   []
    make_install_make_command [/usr/bin/make]
    makepl_arg         []
    mbuild_arg         []
    mbuild_install_arg []
    mbuild_install_build_command [./Build]
    mbuildpl_arg       []
    ncftp              []
    ncftpget           []
    no_proxy           []
    pager              [/usr/bin/less]
    password           undef
    patch              [/usr/bin/patch]
    prefer_installer   [MB]
    prefs_dir          [/Users/jhs/.cpan/prefs]
    prerequisites_policy [ask]
    proxy_pass         undef
    proxy_user         undef
    randomize_urllist  undef
    scan_cache         [atstart]
    shell              [/bin/zsh]
    show_unparsable_versions [0]
    show_upload_date   [0]
    show_zero_versions [0]
    tar                [/usr/bin/tar]
    tar_verbosity      [v]
    term_is_latin      [1]
    term_ornaments     [1]
    test_report        [0]
    unzip              [/usr/bin/unzip]
    urllist           
    use_sqlite         [0]
    username           undef
    wait_list          undef
    wget               [/usr/local/bin/wget]
    yaml_load_code     [0]
    yaml_module        [YAML]


cpan[2]>

Then paste this little snippet, which sets most things right (it's a good decade to use a UTF-8 terminal):
o conf term_is_latin 0
o conf check_sigs 1
o conf make_arg -j3
o conf make_install_arg -j3
o conf makepl_arg PREFIX=/usr/local
o conf mbuildpl_arg --install_base /usr/local
o conf commit

This will have perl use two cores when compiling modules, and use Module::Signature if you install it, which seemed like a nice enough idea (at least if you have gpg installed; you may want to skip the check_sigs part, or install it first, if not -- via brew install gpgme for instance). And, most importantly, it'll put stuff in /usr/local at installation time, so perl will find it at invocation time. (Some day, that might just work right out of the box, in MacOS too.)

And that's it. Try it with cpan Module::Signature for instance, if you enabled that and you'll eventually end up with a fatter /usr/local/lib/perl5/site_perl. You are encouraged to drop other helpful tips here, especially if you know a thing or two about perl or cpan that I totally should have mentioned. Happy hacking! :-)

2011-01-14

Musings on DNA, code and otherwise

From college days, I recall microbiology as one of the more fascinating fields I never opted to pursue, but still developed a latent interest in. The evolved, highly complex and cross-connected execution context of biology, at the deepest levels where it meets (or indeed is) the realities of chemistry and physics speaks to my geek genes. There are so many levels of exciting, beautiful and interesting stories, events and developments woven together and buried in genome! Not to mention it is open source!

You want to grok something? UTSL! If you don't yet understand it, it's because you are not knowledgeable enough. Go learn! Experiment. Think hard. Figure it out. And then share what you learned, so others can reach longer, make it do more, be more efficient, go faster, taste better, or what have you. I think choosing mad computer science over mad genetics was more of a cultural thing gut draw towards openness; away from the lock-ins of lawyers of looming heavy corporations protecting the intellectual off-spring stemming from the money invested into powering their geeks' forays into the unknown, and toward the almost open eco system of what today amounts to the web and places like github, where people promiscuously and chaotically spin off of each others' work making stuff better together, for fun and profit.

But back to genetic code, as inspired by a read of an article on MS, schizophrenia and bipolar disorder as related to endogenous retroviruses (meaning stuff we all carry as common heritage, though not activated in most of us). One of the things we were taught in my classes was about the huge amount of introns (DNA between genes that is seemingly not active, as it isn't observed to ever get transcripted into proteins -- which is essentially how microbiological code execution happens) observed in all living organisms (about 98% of human DNA is non-coding DNA). Of course the depth level of the insights we absorbed were rather meagre, and although omnipresent easy-access Wikipedia was not yet around, it felt fairly obvious that the rest, at the very least, would end up having all sorts of other functions or effects under conditions and circumstances that would relate to it somehow. If you have ever researched (or exploited) a buffer overflow in some program, you probably know that wherever the program pointer accidentally ends up, whatever junk or data happens to be in that memory region is suddenly, for all intents and purposes (or despite them :-), is now code! Maybe it will do something interesting. Or nefarious. Probably nefarious, really.

Biology, chemistry and physics, of course, just add a gazillion more dimensions to "functions and effects of things", while also imposing a bus-load of peculiar constraints, and introducing still more environmental conditions from the rather chaotic virtual machine of physics, chemistry and biology (being three different zoom levels at which things happen to shoot your code in the foot) combined.

If you thought debugging code is hard, it's actually a delightful walk in the park, for the most part -- free of all sorts of concerns like the ethics of feeding useful test arrays into your debugger, that your test subjects can't keep dying all the time until you figure it out, and so on, and that we're probably not debugging software that co-evolved on a planetary scale, over a couple of billion years, but was probably caused by, at the very most, a couple of decades worth of ingenuity from probably less than thousands (or at most millions) of humans, all more or less acting with actual intents, often worthy of words like "design" and "intent". We're kind of lucky, that way! And oftentimes, the whole code base is even your very own damn fault! And you could even know full well what every line of your code is supposed to do, even though you might not yet have discovered all the things it should probably also do to work under the conditions it'll be subject to when unforgiving users run it. (Even yourself!)

I wonder how far into the future we have to go to see iLife speaking to the creative class doing justice to its name, providing us with the tools to be creative with the workings of micro- (or, for that matter, even macro-)organisms, in the same manner it's letting today's happy amateurs go wild with arts like graphics, music and video. Lots of people have rather rigid ideas about what amounts to art, science, work, life style, communication and so many other arbitrary things you can do for whichever reasons propel you, based, among other things, on rules, rulers or methods used in each field, motivations behind them, et cetera. Try breaking a few; you end up in far more interesting places. And make and bring friends, along the way!