... I find the pattern matching _very_ elegant. ... Generally I'd say
I don't use it overly often but when I use it it is really handy. ...
I don't use it very often, but when I do, it usually makes an
elegant solution. I think part of the reason it doesn't seem that
way is because you are playing with it in too sterile of an environment.
That last sentence seems an accurate assessment of why it perhaps
doesn't seem much use to you, and what Josh Cheek and Robert Klemme
say about those situations where they use it seems appropriate,
although I haven't personally used it in those types of situations
because my Ruby use is relatively simple.
... This however is already covered by me as the first case (with HIGH
elegance rating) since you are expecting the line to contain exactly two
strings ... and hence the (expected) number of lvalues = number of rvalues.
I do like/understand such application of parallel assignment.
Strangely, that's the situation (number of lvalues == number of
rvalues) when I definitely dislike its use (unless it might be
necessary to ensure all the rvalues are calculated before any
assignment takes place - might side effects make this necessary?), for
two (and a quarter) reasons.
First, whenever I've benchmarked parallel assignment against
individual assignment, I've found the parallel assignment somewhat
slower. The swap is more elegant, but even that seems slower.
Second, parallel assignment can make it difficult to see what is being
assigned to what. In the following, is it instantly obvious what e is
being set to?
# a, b, c, d, e, f, g, h = q, r, s, t, u, v, w, x
If it is instantly obvious, try more l and r values and/or try longer
variable names and/or values and/or split the assignment expression
over multiple lines!
As an actual example, this from Date:
def initialize(ajd=0, of=0, sg=ITALY)
@ajd, @of, @sg = ajd, of, sg
# ...
end
Admittedly it's easy here to see what's being assigned to what, but
even so is that really better than the alternative just below? Is
there a reason for using the parallel assignment in the actual
example, other than aesthetics?
def initialize(ajd=0, of=0, sg=ITALY)
@ajd = ajd; @of = of; @sg = sg
# ...
end
The quarter is the positive side of the negative point of the second,
that explicit individual assignment is easier visually/cognitively
than parallel assignment.
*** benchmarks
require "benchmark"
a = b = c = d = e = f = g = h = nil; x = y = nil
kt = 1_000_000
Benchmark.bm( 22 ) do |bm|
bm.report( "parallel assignment" ) { kt.times{
a, b, c, d, e, f, g, h = 17, 23, 13, 48, 42, 46, 26, 24 } }
bm.report( "individual assignment" ) { kt.times{
a = 17; b = 23; c = 13; d = 48; e = 42; f = 46; g = 26; h = 24 } }
bm.report( "swap elegant" ) { kt.times{
x = 113; y = 355; x, y = y, x } }
bm.report( "swap messy" ) { kt.times{
x = 113; y = 355; z = x; x = y; y = z } }
end
Using Linux, Ruby 1.9.1, but I've had similar results on MS Windows.
user system total real
parallel assignment 0.630000 0.000000 0.630000 ( 0.635576)
individual assignment 0.400000 0.000000 0.400000 ( 0.393652)
swap elegant 0.500000 0.000000 0.500000 ( 0.506171)
swap messy 0.300000 0.000000 0.300000 ( 0.298167)
MS Windows: ruby 1.9.1p430 (2010-08-16 revision 28998) [i386-mingw32]
user system total real
parallel assignment 0.531000 0.000000 0.531000 ( 0.530000)
individual assignment 0.327000 0.000000 0.327000 ( 0.335000)
swap elegant 0.500000 0.000000 0.500000 ( 0.490000)
swap messy 0.296000 0.000000 0.296000 ( 0.300000)
MS Windows: jruby 1.5.3 (ruby 1.8.7 patchlevel 249) (2010-09-28 7ca06d7)
(Java HotSpot(TM) Client VM 1.6.0_14) [x86-java]
user system total real
parallel assignment 0.735000 0.000000 0.735000 ( 0.705000)
individual assignment 0.460000 0.000000 0.460000 ( 0.460000)
swap elegant 0.560000 0.000000 0.560000 ( 0.560000)
swap messy 0.425000 0.000000 0.425000 ( 0.425000)