I just introduced myself to the Ruby splat oprator. And I played with it lot's of way. but the below experiment somehow made me think about it twice :)
我刚才向Ruby splat oprator介绍了自己。而且我玩的很多。但是下面的实验让我想起了两次:)
langs = ["java", "csharp", "ruby", "haskell" ]
# => ["java", "csharp", "ruby", "haskell"]
l1,*,l2 = *langs
# => ["java", "csharp", "ruby", "haskell"]
l1
# => "java"
l2
# => "haskell"
l1,*,*,l2 = *langs
SyntaxError: (irb):27: syntax error, unexpected tSTAR
l1,*,*,l2 = *langs
^
from /usr/bin/irb:12:in `<main>'
Yes, the error is obvious, as I used more then 1 *(splat)
operators in the same argument list.
是的,错误很明显,因为我在同一个参数列表中使用了多个1 *(splat)运算符。
Now I tried to play with it.
现在我试着玩它。
l1,(*),(*),l2 = *langs
# => ["java", "csharp", "ruby", "haskell"]
Ahh! here it works. But couldn't understand why so?
啊!这里有效。但是不明白为什么会这样呢?
l1
# => "java"
l2
# => "haskell"
l1,(*),l2 = *langs
# => ["java", "csharp", "ruby", "haskell"]
l1
# => "java"
l2
# => "ruby"
From the above example it seems that it is doing skipping of array elements.
从上面的例子来看,它似乎正在跳过数组元素。
Questions are :
问题是:
-
(a) what the operator (*) is called?
(a)调用运算符(*)是什么?
-
(b) when I used in splat(*) in the line
l1,*,l2 = *langs
it consumes all the elements -"csharp", "ruby"
. Is there any way to see what*
consumes there technically? Obviously I am teling with the use ifl1,*,l2 = *langs
not byl1,l*,l2 = *langs
.(b)当我在行l1,*,l2 = * lang中使用splat(*)时,它会消耗所有元素 - “csharp”,“ruby”。有什么方法可以看到技术上消耗的东西吗?显然,如果l1,*,l2 = * langs不是l1,l *,l2 = * langs,我会使用它。
3 个解决方案
#1
9
This is due to how parentheses work with parallel assignment as explained by Matz.
这是由于Matz所解释的括号如何与并行分配一起工作。
For example:
例如:
a, b, c = *[1, 2, 3]
a => 1
b => 2
c => 3
Is different than:
不同于:
a, (b, c) = *[1, 2, 3]
a => 1
b => 2
c => nil
Basically, the parenthesis say: assign the right hand element at this index to the variables in the parens. So 2 is assigned to b
, with nothing left at index 1
to assign to c
. Similarly, (*) will take only the element at the given index and distribute it.
基本上,括号表示:将此索引处的右手元素分配给parens中的变量。因此2被分配给b,索引1处没有任何东西被分配给c。类似地,(*)将仅获取给定索引处的元素并分发它。
# the * is interpreted to mean 'take all remaining elements'
a, * = 1, 2, 3, 4
# the * is interpreted to mean 'take all remaining elements except
# the last element'
a, *, c = 1, 2, 3, 4
# incorrect syntax, can't splat more than once on all remaining
# elements
a, *, *, c = 1, 2, 3, 4
# the * is interpreted to mean 'take all elements at index 1'
a, (*), c = 1, 2, 3, 4
# the *'s are interpreted to mean 'take all elements at index 1,
# then again at index 2'
a, (*), (*), c = 1, 2, 3, 4
Typically, the *
operator is used in conjuction with a variable as *foo
- but if not it will hold its place and take element assignments as if it were a variable (essentially discarding them)
通常,*运算符与变量* foo结合使用 - 但如果不是,它将保持其位置并将元素赋值视为变量(实际上是丢弃它们)
#2
6
Think of it this way: The parenthesis by themselves (ignoring a variable name or splat operator) are accessing a single element from the array:
可以这样想:括号(忽略变量名或splat运算符)从数组中访问单个元素:
l1, (), (), l2 = *['a', 'b', 'c', 'd']
^ ^ ^ ^
'a' 'b' 'c' 'd'
If it were an array of arrays, it would make more sense to use parenthesis:
如果它是一个数组数组,使用括号更有意义:
>> l1,(l3, l4),(l5, l6),l2 = *['a', ['b', 'c'], ['d', 'e'], 'f']
=> ["a", ["b", "c"], ["d", "e"], "f"]
>> l1
=> "a"
>> l3
=> "b"
>> l4
=> "c"
>> l5
=> "d"
>> l6
=> "e"
>> l2
=> "f"
Therefore the (*) is taking a single element from the array, and splat-assigning it. The parenthesis themselves take a SINGLE element, the splat then takes that single element and "splats" it.
因此,(*)从数组中获取单个元素,并进行splat分配。括号本身采用SINGLE元素,然后splat接受单个元素并“splats”它。
It's good to note that when performing multi-variable assignment from an array, the splat is not necessary on the array side:
值得注意的是,从阵列执行多变量赋值时,阵列侧不需要splat:
>> a,b,c = ['a', 'b', 'c']
=> ["a", "b", "c"]
>> a
=> "a"
>> b
=> "b"
>> c
=> "c"
#3
6
(*)
really just reads one element from the right side. Consider this example, which has a fifth element in the langs
array:
(*)实际上只是从右侧读取一个元素。考虑这个例子,它在langs数组中有第五个元素:
langs = ["java", "csharp", "ruby", "haskell", "python" ]
So when you use a normal splat, you get:
所以当你使用普通的splat时,你得到:
l1,*,l2 = langs
l1 #=> "java"
l2 #=> "python"
in contrast to your example with the parentheses:
与括号中的示例形成对比:
l1,(*),(*),l2 = langs
l1 #=> "java"
l2 #=> "haskell"
I want to mention though, that for this case you would normally use _
to assign the middle values to "nothing" (equivalent to the last example):
我想提一下,对于这种情况,你通常会使用_来将中间值分配给“nothing”(相当于最后一个例子):
l1,_,_,l2 = langs
l1 #=> "java"
l2 #=> "haskell"
If you want to see what ended up being inside of the middle values, you can explicitly assign the values to variables like so:
如果要查看最终位于中间值内的内容,可以将值显式分配给变量,如下所示:
l1,*m,l2 = *langs
l1 #=> "java"
l2 #=> "python"
m #=> ["csharp","ruby","haskell"]
or with the other example:
或者与另一个例子:
l1,(*m1),(*m2),l2 = langs
l1 #=> "java"
l2 #=> "haskell"
m1 #=> ["csharp"]
m2 #=> ["ruby"]
So i hope this makes clear that (*)
isnt an operator on its own, but really just a splat inside parentheses and therefore has no own name.
所以我希望这表明(*)不是一个独立的运算符,但实际上只是括号内的splat,因此没有自己的名字。
#1
9
This is due to how parentheses work with parallel assignment as explained by Matz.
这是由于Matz所解释的括号如何与并行分配一起工作。
For example:
例如:
a, b, c = *[1, 2, 3]
a => 1
b => 2
c => 3
Is different than:
不同于:
a, (b, c) = *[1, 2, 3]
a => 1
b => 2
c => nil
Basically, the parenthesis say: assign the right hand element at this index to the variables in the parens. So 2 is assigned to b
, with nothing left at index 1
to assign to c
. Similarly, (*) will take only the element at the given index and distribute it.
基本上,括号表示:将此索引处的右手元素分配给parens中的变量。因此2被分配给b,索引1处没有任何东西被分配给c。类似地,(*)将仅获取给定索引处的元素并分发它。
# the * is interpreted to mean 'take all remaining elements'
a, * = 1, 2, 3, 4
# the * is interpreted to mean 'take all remaining elements except
# the last element'
a, *, c = 1, 2, 3, 4
# incorrect syntax, can't splat more than once on all remaining
# elements
a, *, *, c = 1, 2, 3, 4
# the * is interpreted to mean 'take all elements at index 1'
a, (*), c = 1, 2, 3, 4
# the *'s are interpreted to mean 'take all elements at index 1,
# then again at index 2'
a, (*), (*), c = 1, 2, 3, 4
Typically, the *
operator is used in conjuction with a variable as *foo
- but if not it will hold its place and take element assignments as if it were a variable (essentially discarding them)
通常,*运算符与变量* foo结合使用 - 但如果不是,它将保持其位置并将元素赋值视为变量(实际上是丢弃它们)
#2
6
Think of it this way: The parenthesis by themselves (ignoring a variable name or splat operator) are accessing a single element from the array:
可以这样想:括号(忽略变量名或splat运算符)从数组中访问单个元素:
l1, (), (), l2 = *['a', 'b', 'c', 'd']
^ ^ ^ ^
'a' 'b' 'c' 'd'
If it were an array of arrays, it would make more sense to use parenthesis:
如果它是一个数组数组,使用括号更有意义:
>> l1,(l3, l4),(l5, l6),l2 = *['a', ['b', 'c'], ['d', 'e'], 'f']
=> ["a", ["b", "c"], ["d", "e"], "f"]
>> l1
=> "a"
>> l3
=> "b"
>> l4
=> "c"
>> l5
=> "d"
>> l6
=> "e"
>> l2
=> "f"
Therefore the (*) is taking a single element from the array, and splat-assigning it. The parenthesis themselves take a SINGLE element, the splat then takes that single element and "splats" it.
因此,(*)从数组中获取单个元素,并进行splat分配。括号本身采用SINGLE元素,然后splat接受单个元素并“splats”它。
It's good to note that when performing multi-variable assignment from an array, the splat is not necessary on the array side:
值得注意的是,从阵列执行多变量赋值时,阵列侧不需要splat:
>> a,b,c = ['a', 'b', 'c']
=> ["a", "b", "c"]
>> a
=> "a"
>> b
=> "b"
>> c
=> "c"
#3
6
(*)
really just reads one element from the right side. Consider this example, which has a fifth element in the langs
array:
(*)实际上只是从右侧读取一个元素。考虑这个例子,它在langs数组中有第五个元素:
langs = ["java", "csharp", "ruby", "haskell", "python" ]
So when you use a normal splat, you get:
所以当你使用普通的splat时,你得到:
l1,*,l2 = langs
l1 #=> "java"
l2 #=> "python"
in contrast to your example with the parentheses:
与括号中的示例形成对比:
l1,(*),(*),l2 = langs
l1 #=> "java"
l2 #=> "haskell"
I want to mention though, that for this case you would normally use _
to assign the middle values to "nothing" (equivalent to the last example):
我想提一下,对于这种情况,你通常会使用_来将中间值分配给“nothing”(相当于最后一个例子):
l1,_,_,l2 = langs
l1 #=> "java"
l2 #=> "haskell"
If you want to see what ended up being inside of the middle values, you can explicitly assign the values to variables like so:
如果要查看最终位于中间值内的内容,可以将值显式分配给变量,如下所示:
l1,*m,l2 = *langs
l1 #=> "java"
l2 #=> "python"
m #=> ["csharp","ruby","haskell"]
or with the other example:
或者与另一个例子:
l1,(*m1),(*m2),l2 = langs
l1 #=> "java"
l2 #=> "haskell"
m1 #=> ["csharp"]
m2 #=> ["ruby"]
So i hope this makes clear that (*)
isnt an operator on its own, but really just a splat inside parentheses and therefore has no own name.
所以我希望这表明(*)不是一个独立的运算符,但实际上只是括号内的splat,因此没有自己的名字。