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 ]

educated_foo (3106)

educated_foo
  (email not shown publicly)

Journal of educated_foo (3106)

Saturday May 09, 2009
09:59 PM

Correction on platypi (?)

I can't be bothered to create yet another login on chromatic's site, but want to offer a correction

As the difficulty for creating sane biological taxonomies indicates, the real world does not lend itself to such artificial simplicity. (Extinction of the duck-billed platypus might help, but I'd miss the little guys -- and besides that, I can't give birth to live young myself, so I'm obviously not a mammal.)

The duck-billed platypus is a monotreme, an ancient relative of mammals. Before we knew about genes, one might think that it was part duck and part beaver, but we know about genes now, and therefore better understand evolution. It's pretty straightforward to fit it into a phylogeny, and horizontal gene transfer has nothing to do with it. I agree that single inheritance is a crappy way to design software, but this is a bad example.

Friday May 01, 2009
12:17 PM

Test

Was that a network error, a user error, or did something I posted just get disappeared?

Saturday February 21, 2009
10:43 PM

There's a reason...

In response to chromatic's latest maunderings, there's a reason that the Perl core heeds "the DarkPAN" -- it's the same reason that "the DarkPAN" is still written in Perl. Language implementors have no obligation to maintain backward compatibility, just like language users have no obligation to keep using a language. It's "insane" to think that a script written for Perl 5.6 will work with Perl 5.10, just like it was "insane" to think that a script written to run on HPUX would run on AIX, Solaris, BSD, etc. Perl is great because of its stability, and breaking that because... whatever it is you want... is insane.

Sunday December 16, 2007
03:29 PM

TIMTOWTDI in Emacs, too.

Devel::PerlySense has been getting quite a bit of (apparently well-deserved) attention lately. As the author of Sepia, a long-existing but apparently little-used Emacs Perl development module, I thought now would be a good time to post a diary here. For those of you who tried an earlier version, Sepia is considerably more stable and better-documented in versions 0.9x, but needs more users to acquire polish.

Sepia aims to make Emacs the kind of interactive development environment for Perl that it already is for Emacs Lisp. This involves a number of components:

  • Interactive evaluation: Supports both a REPL and a scratch buffer. The REPL uses the Perl debugger hooks to allow breakpoints and recovery from die, and Devel::LexAlias to inspect and change lexicals.
  • Source navigation: Finds definitions, callers, and callees. This is supported by querying the running Perl process rather than through PPI.
  • Documentation: Displays minibuffer documentation (eldoc) for builtins and some user functions, and supports POD browsing.
  • Completion: Completes variable, function, and module names based on the running Perl process.

Not having used Devel::PerlySense, I won't try to make a detailed comparison, but my impression is that Devel::PerlySense is geared toward off-line development (uses PPI, has a class browser, etc.), while Sepia is geared toward on-line development (supports interaction, value inspection, debugging). So give both a try, and see which style suits you best.

Monday May 21, 2007
12:54 PM

Defining "DSL", or eternal recurrence in software

(Inspired by chromatic's recent musings...)

I want a function to take the mean of some data:

$x = mean \@data;

Hm.... I want to ignore NaN and Inf sometimes; I'll add a flag for it:

$x = mean \@data, 1;

But I may also want to trim outliers; I'll use keyword arguments:

$x = mean \@data, skipinf => 1, trim => 0.1;

Whoa, this is getting complicated; I'll make it an Object:

$x = new Mean(@data);
$x->{skipinf}=1;
$x->{trim}=0.1;
$y = $x->value

OMG, no encapsulation, I'll make accessors:

$x = new Mean;
$x->setData(\@data);
$x->setSkipInf(1);
$x->setTrim(0.1);
$y = $x->value

But now I have to do this just to do a simple mean:

$x = new Mean;
$x->setData(\@data);
$y = $x->value

I know, I'll create a little language for means:

$x = mean \@data, trim => 0.1, skipinf => 1;

Then I can write in the domain terminology, and taking the mean is easy:

$x = mean \@data;

...and thus we see how "writing interfaces that don't suck" became "creating little languages."

Thursday September 30, 2004
11:27 PM

script vs. applescript

So I need something to kill time during the debates and further
increase my level of frustration. Safari doesn't have a saved
sessions. Let's try a bit of applescript...

tell application "Safari"
        set urls to URL of every document
        -- tbd: how do I write a file in AS?
end tell

No love -- this only saves the first tab of each window. Curse.
Google around a bit. Curse a bit more when I find out what's
involved, and when I can't make the cut-and-paste code to write a file
work...

#!/usr/bin/env perl

sub osascript($)
{
        my $cmd = shift;
        local *O;
        open O, "|osascript > /tmp/osa.$$";
        $cmd =~ s/\n/\r/g;
        print O $cmd;
        close O;
        open IN, "/tmp/osa.$$" or die $!;
        unlink "/tmp/osa.$$";
        return split /\r/, join '', <IN>;
}

sub get_docs
{
        osascript <<'END';
tell application "System Events"
        set urls to {}
        tell process "Safari"
                repeat with w in every window
                        tell w
                                repeat with b in every radio button
                                        click b
                                        tell application "Safari"
                                                set urls to urls & (URL of first document)
                                        end tell
                                end repeat
                        end tell
                end repeat
        end tell
        set old_delim to AppleScript's text item delimiters
        set AppleScript's text item delimiters to return
        set urls to urls as text
        set AppleScript's text item delimiters to old_delim
        urls
end tell
END
}

sub restore_docs
{
        my $docthing = '{'.(join ',', map { qq{"$_"} } grep $_, @_).'}';
        osascript <<END;
tell application "System Events"
        set urls to $docthing
        tell application "Safari"
                repeat with u in urls
                        open location u
                end repeat
        end tell
end tell
END
}

@ARGV = grep $_,@ARGV; # wtf: quicksilver passes us an empty arg.
if (@ARGV) {
        $op = shift;
} else {
        $pf = "$ENV{HOME}/.safari-state";
        if ($0 =~ /safari-save(?:\.pl)?$/) {
                $op = 'save';
                open STDOUT, ">$pf" or die "$0: $pf: $!";
        } elsif ($0 =~ /safari-load(?:\.pl)?$/) {
                $op = 'load';
                open STDIN, $pf or die $!;
        } else {
                die;
        }
}

if ($op =~ /^s/) {
        print STDOUT "$_\n" for get_docs;
} elsif ($op =~ /^l/) {
        my @docs = map {chomp;$_} <STDIN>;
        restore_docs(@docs);
}
...add it to my Quicksilver path. Hack-tastic.