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.
Was that a network error, a user error, or did something I posted just get disappeared?
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.
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:
die, and Devel::LexAlias to inspect and
change lexicals.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.
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."
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 >
$cmd =~ s/\n/\r/g;
print O $cmd;
close O;
open IN, "/tmp/osa.$$" or die $!;
unlink "/tmp/osa.$$";
return split
}
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 =~
$op = 'save';
open STDOUT, ">$pf" or die "$0: $pf: $!";
} elsif ($0 =~
$op = 'load';
open STDIN, $pf or die $!;
} else {
die;
}
}
if ($op =~
print STDOUT "$_\n" for get_docs;
} elsif ($op =~
my @docs = map {chomp;$_} <STDIN>;
restore_docs(@docs);
}