What does "(test1, test2, test3="3", test4="4", test5 = "5", test6 = "6")" do?
This question is based off some really odd code I recently found in a colleagues work. He claims not to know how it works only he copied it from somewhere else. That's not good enough for me, I want to understand what's going on here.
If we have something like:
(test1, test2, test3="3", test4="4")
The result will be that test1 == "3"
, test2 == "4"
, test3 == nil
and test4 == "4"
.
I understand why this happens, but if we do something like:
(test1, test2, test3="3", test4="4", test5 = "5", test6 = "6")
now the result is test1 == "3"
, test2 == "4开发者_JAVA技巧"
, test3 == "5"
, test4 == "4"
, test5 == "5"
, test6 == "6"
.
Why isn't test5 == nil
?
It looks like it's executing like this:
(test1, test2, test3) = ("3"), (test4 = "4"), (test5 = "5"), (test6 = "6")
# Equivalent:
test1 = "3"
test2 = test4 = "4"
test3 = test5 = "5"
; test6 = "6"
An assignment statement returns the RHS (right hand side of the expression), which is how a = b = 4
sets both a
and b
to 4:
a = b = 4
-> a = (b = 4) // Has the "side effect" of setting b to 4
-> a = 4 // a is now set to the result of (b = 4)
Keeping this in mind, as well as the fact that Ruby allows for multiple assignments in one statement, your statement can be rewritten (Ruby sees commas and an equals sign, and thinks that you're trying to do multiple assignments, with the first equals splitting the LHS (left hand side) and RHS):
test1, test2, test3="3", test4="4", test5 = "5", test6 = "6"
-> test1, test2, test3 = "3", (test4 = "4"), (test5 = "5"), (test6 = "6")
The RHS is evaluated first, which leaves us with:
test1, test2, test3 = "3", "4", "5", "6"
with the side effect of setting test4
to "4"
, test5
to "5"
, and test6
to "6"
.
Then the LHS is evaluated, and can be rewritten as:
test1 = "3"
test2 = "4"
test3 = "5"
// since there are 3 items on the LHS and 4 on the RHS, nothing is assigned to "6"
So at the end of the statement, six variables will have been set:
test1 == "3"
test2 == "4"
test3 == "5"
test4 == "4"
test5 == "5"
test6 == "6"
When I run your second example:
(test1, test2, test3="3", test4="4", test5 = "5", test6 = "6")
I get a different result from what you report:
test1=="3", test2=="4", test3=="5", test4=="4", test5=="5", test6=="6"
(note that test4 is "4", not "6")
Which makes sense to me, because it parses like this:
((test1, test2, test3) = ("3", (test4="4", (test5 = "5", (test6 = "6")))))
So you get an evaluation something like this:
((test1, test2, test3) = ("3", (test4="4", (test5 = "5", (test6 = "6")))))
[assign "6" to test6]
((test1, test2, test3) = ("3", (test4="4", (test5 = "5", "6"))))
[assign "5" to test5]
((test1, test2, test3) = ("3", (test4="4", "5", "6")))
[assign "4" to test4]
((test1, test2, test3) = ("3", "4", "5", "6"))
[assign "3", "4", and "5" to test1, test2, and test3 respectively]
精彩评论