Beefy Boxes and Bandwidth Generously Provided by pair Networks
Problems? Is your data what you think it is?
 
PerlMonks  

Re: String concatenation (join++)

by tye (Sage)
on Apr 11, 2012 at 20:41 UTC ( [id://964621]=note: print w/replies, xml ) Need Help??


in reply to String concatenation

Perhaps if you use Acme::ESP, you could see what the strings think about it (which they prefer).

For your (contrived?) example, there's really very little to hang a preference on. And you left out:

$string = sprintf "%s%s%s", $var1, $var2, $var3;

But if the nature of the concatenation is such that it is likely to become more complicated later on (a case I very often run into), then I'll usually go with join as, after years of doing a lot of concatenating of strings, join() was the one method that scaled the best (by far).

For the exact case you show, I'd just do "$var1$var2$var3", though. I only resort to ${var1} for cases like "${var1}'s ...", and even then I'll often go with an alternative like "$var1\'s ...".

I've come to quite dislike extensive use of . (Perl5's string concatenation operator). It has the wrong precedence for so many things so I'm pretty unlikely to use more than one . in any given expression. Once I've got two .s, there's likely to eventually be more and then I'll want 1+$index in there:

% perl -e'print "found " . 1+2 . " items" . $/' 2 items

The above is not a pleasant thing to stumble over, especially when the evidence is further separated from the source.

I'm not bothered by "Found 1+$index items" not doing the addition because it doesn't look at all like it should (to me, at least). But I find ... . $x+$y . ... or even ... . 0+@items . ... to be pitfalls. I've become somewhat attuned to spot such a mistake, but it can still slip past me. So I mostly just spot "over-use of ." as a problem in itself instead.

Note that .= doesn't have that problem (and can be quite efficient), so I often use it (when appropriate).

And I rarely use sprintf, in part because I dislike the "correspondence at a distance" problem between the format specs and the values. (Also because I've seen too many bugs due to sprintf "...$var...", ....) I'm more likely to end up with something like:

join '', ..., sprintf( "%6.2f", $amount ), ..., ;

But just yesterday I started to write:

join '', $cmp, " '", $count, " ", $unit, "'::interval";

(except two of the three scalars were moderately complex expressions) but almost immediately realized that this was an exception to my learned preference. So, before I even had much of it typed in, I changed it to the much clearer:

sprintf "%s '%d %s'::interval", ...;

"$cmp '$count $unit'::interval" would have been even better except that $cmp and $unit were actually too complex to leave such readable (but not complex enough to really warrant their own line and own variable).

Going to a further extreme, you end up with templating systems. But my experience is that most things that start out as even pretty complicated concatenations don't end up turning into something that fits well into a templating system. Heck, at my current job I am often taking things that are being done in the templating system and replacing them with mostly join in the process of making the code clearer and easier to maintain. I find templating systems are best at cases of a lot of hard-coded text with relatively infrequent replacements. And the volume of the hard-coded part has to be pretty large before real templating pays off over join().

And I'll just spare everybody my thoughts on how bad here-docs are for the vast majority of cases. :)

- tye        

Replies are listed 'Best First'.
Re^2: String concatenation (join++)
by thekostya (Initiate) on Mar 16, 2016 at 09:47 UTC
    You forgot one more method of concatenation via substr.


    1. substr($a, length($a), 0, $b);
    or
    2. substr($a, length($a)) = $b;

    This concatenation is faster for very long strings.

    For string size 10 - 100 symbols fastest way is $a . $b and join

    For string size ~1 Mb fastest ways join, substr and $a.$b

    For strings size ~1Gb :) fastest ways are substr, strange method "@{[$a, $b]}" :) and join

    Join has good speed for all variants.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://964621]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others learning in the Monastery: (5)
As of 2024-03-28 16:00 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found