in reply to Re: Perl style: Arguing against three-argument join() (++join '')
in thread Perl style: Arguing against three-argument join()
You start out with "you have $count left" and then some refactoring leads to $count being replaced by $new+$old and you have too much sense to do something bizarre like "you have ${\($new+$old)} left" (which doesn't scale well anyway when the strings and expressions grow to the point that more than one line is called for) so the next obvious choice is "you have " . $new+$old . " left" which is, unfortunately, quite wrong. Fixing it starts to give you a hint of how concatenation can suck, "you have " . ($new+$old) . " left".Lessee, in Perl 6 we fixed the precedence of concatenation with respect to + (at your suggestion), so that part's okay...
If you want to keep your current style you can write:
but you can also say:$html ~= [~] createLink( $USER, "you" ), " have ", $new + $old, " message", 1 == $new+$old ?? "" !! "s", " left";
or you can interpolate with closures:$html ~= createLink( $USER, "you" ) ~ " have " ~ $new + $old ~ " message" ~ (1 == $new+$old ? "" : "s") ~ " left";
or spread it out blockishly:$html ~= "{createLink $USER, "you"} have { $new + $old } message{" +s" x ($new+$old == 1)} left";
or you can use methods and subs:$html ~= "{ createLink $USER, "you" } have { $new + $old } message{ "s" x ($new+$old == 1) } left";
or some combination of those...$html ~= "$USER.createLink("you") have &pl($new+$old,"message") le +ft";
I've also come to dislike sprintf for such concatenations. I don't like the out-of-order nature between non-format-specifier parts of the first argument and the other items being concatenated into the result. And I don't like the separation between the format specs and the values being formatted. I've also seen too many mistakes like sprintf "bleh $foo%s bar", complex($expr) where $foo might contain a % character. In most cases I find that the majority of the parts are simply being concatenated so if any of the items need 'printf' formatting, then I use sprintf to format just that item:
$html .= join '',
createLink( $USER, "you" ),
" have a ",
sprintf( "%+.2f", $rating ),
" rating";
that would now look more like:
or maybe just:$html ~= [~] createLink( $USER, "you" ), " have a ", $rating.fmt("%+.2f"), " rating";
$html ~= "{createLink $USER, "you"} have a $rating.fmt("%+.2f") ra +ting";
Which might lead to the suggestion of here-docs, which I really dislike since they can't be indented and can fail very confusingly in the face of invisible trailing whitespace.Well, we fixed the indent part at least, though you're still on your own with trailing whitespace.
I hope that leads to some to think of suggesting a "real" templating system. That's often an excellent suggestion. Of course it isn't an appropriate replacement for tons of cases of concatenation. (:Indeed. Though with enough Ways To Do It you almost don't need a templating system... :)
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re^3: Perl style: Arguing against three-argument join() (Perl 6)
by tye (Sage) on Jan 25, 2008 at 03:12 UTC | |
by TimToady (Parson) on Jan 25, 2008 at 06:26 UTC | |
by tye (Sage) on Jan 25, 2008 at 06:31 UTC | |
by BrowserUk (Patriarch) on Jan 25, 2008 at 03:38 UTC | |
|
Re^3: Perl style: Arguing against three-argument join() (++join '')
by dragonchild (Archbishop) on Jan 25, 2008 at 00:10 UTC | |
by TimToady (Parson) on Jan 25, 2008 at 00:17 UTC | |
by dragonchild (Archbishop) on Jan 25, 2008 at 03:51 UTC |