Why does the Ruby splat not work for array coercion in conditional assignment? -


although splat (*) construct commonly referred splat operator, clear different beast, compared other unary operators negation (!) operator.

the splat works fine on it's own (i.e. not wrapped in brackets) when used in assignment (=), produces error when used conditional assignment (||=). example:

a = *(1..3) #=> [1, 2, 3]  b ||= *(1..3) syntaxerror: (irb):65: syntax error, unexpected * 

i not looking alternative ways of doing same thing, looking better understanding of ruby internals explain why usage of splat construct works in first case not in second.

here's understanding of practical goal of splat. ruby 2.2 mri/kri/yarv.

ruby splat destructures object array during assignment.

these examples provide same result, when a falsey:

a = *(1..3) = * (1..3) =* (1..3) = *1..3 = * 1..3 = * || (1..3) = * [1, 2, 3] => [1, 2, 3] 

the splat destructuring during assigment, if wrote this:

a = [1, 2, 3] 

(note: splat calls #to_a. means when splat array, there's no change. means can define own kinds of destructuring class of own, if wish.)

but these statements fail:

*(1..3) * 1..3 * [1,2,3] false || *(1..3) x = x ? x : *(1..3)  => syntaxerror 

these statements fail because there's no assignment happening when splat occurs.

your question special case:

b ||= *(1..3) 

ruby expands to:

b = b || *(1..3) 

this statement fails because there's no assignment happening when splat occurs.

if need solve in own code, can use temp var, such as:

b ||= (x=*(1..3)) 

worth mentioning: there's entirely different use of splat when it's on left hand side of expression. splat low-priority greedy collector during parallel assignment.

examples:

*a, b = [1, 2, 3]  #=> [1, 2], b 3 a, *b = [1, 2, 3]  #=> 1, b [2, 3] 

so parse:

*a = (1..3)  #=> (1..3) 

it sets a results on right hand side, i.e. range.

in rare case splat can understood either destructurer or collector, destructurer has precendence.

this line:

x = * y = (1..3) 

evaluates this:

x = *(y = (1..3))  

not this:

x = (*y = (1..3))  

Comments

Popular posts from this blog

jquery - How do you format the date used in the popover widget title of FullCalendar? -

asp.net mvc - SSO between MVCForum and Umbraco7 -

Python Tkinter keyboard using bind -