Chris's Wiki :: blog/programming/ProgrammerLaziness Commentshttps://utcc.utoronto.ca/~cks/space/blog/programming/ProgrammerLaziness?atomcommentsDWiki2010-09-07T03:27:15ZRecent comments in Chris's Wiki :: blog/programming/ProgrammerLaziness.By Chris Siebenmann on /blog/programming/ProgrammerLazinesstag:CSpace:blog/programming/ProgrammerLaziness:61184ece3b079423f59a9d8512d8e459acd9499fChris Siebenmann<div class="wikitext"><p>The problem with bookmarks is that I ignore them even more than I already
ignore all of those iconified windows. There is effectively no chance that
I will ever read anything that I have saved in a file or bookmarked as
'to read someday'.</p>
<p>(Possibly this is my real problem, of course.)</p>
</div>2010-09-07T03:27:15ZFrom 88.97.233.154 on /blog/programming/ProgrammerLazinesstag:CSpace:blog/programming/ProgrammerLaziness:7f40307b2f7db4e177233ad148347641d4153e88From 88.97.233.154<div class="wikitext"><p>Wow, what a hammer. Have you considered using bookmarks? Either locally or in the cloud :)</p>
</div>2010-09-06T12:08:21ZFrom 134.95.198.212 on /blog/programming/ProgrammerLazinesstag:CSpace:blog/programming/ProgrammerLaziness:309bd0bcbc69b3bcbdc5a4cea4c32d5fbb383edfFrom 134.95.198.212<div class="wikitext"><p>That’s actually not terribly horrible. If I were a potential user of it, I wouldn’t particularly itch to fix it up. (I am eternally cursed with my good grasp of the language when I go shopping for irssi scripts. I <em>always</em> have to spend a long time pummelling them into shape before I can bear to use them.)</p>
<p>I think <code>setup_id</code> can be written like this:</p>
<pre>
sub setup_id {
my ( $event ) = @_;
my $wid = $event->_win_id;
return $byid{$wid} ||= WinData->new(
wid => $wid,
icon_x => 0,
icon_y => 0,
);
}
</pre>
<p>Also, I’d write <code>fvwm_quote</code> like this:</p>
<pre>
sub fvwm_quote { map { s(")(\")g; s(\$)($$)g; $_ } my @copy = @_ }
</pre>
<p>That way you can pass in any number of strings to quote, and get them all back quoted, in one fell swoop.</p>
<p>The first line of your event handlers is unfortunately not really generalisable as Perl 5 so far does not have formal subroutine parameters. And generalising only the second line is too much effort to go through for this particular script.</p>
<p>Particularly since the whole <code>setup_id</code> function isn’t really necessary.</p>
<p>If I’d written it, I’d have used a simple hash of hashes instead of the <code>WinData</code> class; that’s about it. One nice thing about Perl (which has its downsides too occasionally, though I find them far outweighed by its convenience) is called autovivification. What that means is that in expressions on the left side of some form of assignment, intermediate levels of data structure will automatically be created for you if they don’t already exist: you can write <code>$hash{$foo}{$bar}{$baz} = $quux</code> even if <code>$hash{$foo}</code> doesn’t already exist. A new hash will automatically be assigned to it on your behalf, as well as subsequently to <code>$hash{$foo}{$bar}</code>, so that you assignment to <code>$hash{$foo}{$bar}{$baz}</code> can succeed. Therefor, you can write this:</p>
<pre>
$module->add_handler(M_WINDOW_NAME, sub {
my ($self, $event) = @_;
my $wi = setup_id($event);
$wi->name($event->_name);
});
</pre>
<p>as just this (assuming you had a hash <code>%wininfo</code> and not <code>%byid</code>):</p>
<pre>
$module->add_handler(M_WINDOW_NAME, sub {
my ($self, $event) = @_;
$wininfo{$event->_win_id}{name} = $event->_name;
});
</pre>
<p>There is no need to manually make sure that a hash exists in <code>$wininfo{$event->_win_id}</code>, as one will automatically be created if not.</p>
<p>Modulo lack of the <code>WinInfo</code> class and <code>setup_id</code> function, and hash access rather than method calls in the <code>M_END_WINDOWLIST</code> handler, the script would be essentially the same.</p>
<p>If I did feel like using objects for that purpose I’d probably have used <a href="http://p3rl.org/Object::Tiny::Lvalue">Object::Tiny::Lvalue</a>… no one uses Class::Struct these days. I’d also move <code>setup_id</code> into WinInfo as a class method <code>summon_for_event</code> or such and would write the repetitive handlers as instance methods, with the event handlers using the former to delegate to one of the latter. That way you could boil down the repetitive handler bits to just this:</p>
<pre>
my %handler = (
pull_frame_xy => M_CONFIGURE_WINDOW,
pull_name => M_WINDOW_NAME,
# ...
);
while (my ($method, $mask) = each %handler) {
$module->add_handler($mask, sub {
my ($self, $event) = @_;
WinInfo->summon_for($event)->$method($event);
});
}
</pre>
<p>However. that’s just over-engineering for your case.</p>
<p>—<a href="http://plasmasturm.org/">Aristotle Pagaltzis</a></p>
</div>2010-09-04T12:30:58Z