perlmeditation
Aristotle
<p>The recent [id://532275] discussion reminded me of a huge pet peeve of mine about Perl (and hugely peevish too, I know): it’s such a pain to test string length if you want to accept undefined values without emitting warnings. You have to write something like this:</p>
<c>
$foo if defined $str and length $str;
</c>
<p>It’s so redundant and verbose that people will often simply do</p>
<c>
$foo if $str;
</c>
<p>and accept that a value of <tt>0</tt> or <tt>"0"</tt> will produce false negatives with a shrug.</p>
<p>In other words, the easy and obvious way is wrong.</p>
<p>That could have been avoided so simply:</p>
<c>
BEGIN {
*CORE::GLOBAL::length = sub(;$) {
defined $_[0] ? CORE::length( $_[0] ) : undef;
};
}
</c>
<p>The above test for string length then becomes this:</p>
<c>
$foo if length $str;
</c>
<p>Since undef silently evaluates to false in boolean context, same as 0, this never throws an <i>uninitialized</i> warning and does the right thing. This version of [doc://length] is also more useful, since you can tell undefs from empty strings just by looking at the return value, without an extra [doc://defined] test. Granted, now you have to check the return value for definedness if you want to use it in calculations, but the situation does not actually change, since you need a definedness test in either case – either on the passed scalar or on [doc://length]’s return value.</p>
<p>I’ve been using this in some scripts for a while, and I <em>love</em> it. I can’t think of a single reason why anyone would want to have [doc://length]’s current behaviour of returning 0 while throwing a warning on undef scalars, as opposed to returning undef without a complaint. The latter seems more useful and/or less annoying in every case I can come up with.</p>
<p>Of course, it’s way too late to do anything about this now. I daren’t use it in any complex codebase that relies on a lot of CPAN code either. Maybe something to be dealt with using [mod://feature]?</p>
<p>Oh well.</p>
<p align="right" class="pmsig pmsig-114691"><i>Makeshifts last the longest.</i></p>