I wrote this obtuse little function to display six different IRC channels on freenode at once.
(defun irc-java ()
(interactive)
(delete-other-windows)
(switch-to-buffer (get-buffer "#perl"))
(let* (
(p (frame-parameters))
(width (cdr (assoc 'width (frame-parameters))))
(height (cdr (assoc 'height (frame-parameters))))
)
(split-window-horizontally nil)
(split-window-vertically (/ height 3))
(other-window 1)
(switch-to-buffer (get-buffer "#perl6"))
(split-window-vertically)
(switch-to-buffer (get-buffer "#squeak"))
(other-window 2)
(switch-to-buffer (get-buffer "#glassfish"))
(split-window-vertically (/ height 3))
(other-window 1)
(switch-to-buffer (get-buffer "#spring"))
(split-window-vertically)
(other-window 1)
(switch-to-buffer (get-buffer "#java-talk"))
)
)
Hi,
For your amusement, here's a very small uuencode program.
perl -0777 -e '$uue = pack u, <>; print "begin 0644 $ARGV\n${uue}end\n"' your-file.bin
I broke $work yesterday when a change I'd made that I thought was mundane was not in fact. I'd changed some code from: if ( keys %$hash_ref ) {
to if ( %$hash_ref ) {
under the theory that we weren't supporting any perl less than our current production at perl-5.10.0.
What I'd completely missed was that $hash_ref
might be undef
and that keys %$...
would auto-vivify the hash if necessary. Previously, the hash would be created as a side effect of dereferencing it. Afterward, I got an exception because the hash wasn't being automatically created just by looking at it.
The reason for this is keys()
is actually an lvalue, something you can assign to. The meaning of keys( %... ) = 8
is actually fairly obscure and not what you would guess if you haven't read the documentation for keys()
. Because keys()
is an lvalue, the dereference %$...
will auto-vivify anything necessary because I might want to modify it.
When I dropped the usage of something strictly defined as an lvalue function, the dereference stopped auto-vivifying and now I had exceptions in production. Wheee!
Did you know you can modify perl's readonly constants for undef, true and false? Yep.
&Internals::SvREADONLY( \ !!1, 0 );
${ \ !!1 } = 'ponies!';
&Internals::SvREADONLY( \ !!1, 1 );
print !!1; # ponies!
Same thing for \ undef and \ !!0.
Clever Regexps vs Multiple Simple Regexps:
In reading some code I ran across the expression s/^\s*|\s*$//g
which is a trim function. It is not the optimal way to write this. The
optimal way is two simpler expressions: s/^\s+//;
s/\s+$//
. Justification follows.
Conclusion:
Use of +
instead of *
means regexps that will would do no
effective work will also fail to match. Failing to match when the
work would be useless yielded some 3x to 4x improvement.
Use of multiple simpler patterns like s/^...//;s/...$//
instead of
compound patterns like s/^...|...$//g
enabled boundary checking
optimizations.
Testing:
String length:
long: +80 chars
short: -80 chars
Pre/postfixes:
pre/post: " string "
pre: " string"
post: "string "
base: "string"
Coding styles:
g*: s/^\s*|\s*$//g
g+: s/^\s+|\s+$//g
2*: s/^\s*//
s/\s*$//
2+: s/^\s+//
s/\s+$//
Calculated results:
>> short pre 2+ 1638810/s
>> short base 2+ 1622457/s
>> short post 2+ 1351812/s
>> short pre/post 2+ 1152253/s
>> long base 2+ 564477/s
>> long pre 2+ 534890/s
short base +g 532709/s
short post +g 502626/s
>> long post 2+ 501015/s
short pre +g 479683/s
short pre/post +g 465137/s
>> long pre/post 2+ 463741/s
short base 2* 462448/s
short pre 2* 456719/s
short pre/post 2* 450081/s
short post 2* 449661/s
short base *g 394226/s
short pre *g 384360/s
short post *g 367736/s
short pre/post *g 367624/s
long post 2* 114832/s
long base 2* 113787/s
long pre 2* 110305/s
long pre/post 2* 110169/s
long post +g 100847/s
long base +g 99830/s
long pre +g 98871/s
long pre/post +g 98331/s
long base *g 87066/s
long post *g 86520/s
long pre *g 84080/s
long pre/post *g 81429/s