Что делает "(test1, test2, test3 =" 3 ", test4 =" 4 ", test5 =" 5 ", test6 =" 6 ")"? - PullRequest
3 голосов
/ 18 июня 2010

Этот вопрос основан на каком-то действительно странном коде, который я недавно нашел в работе коллег.Он утверждает, что не знает, как это работает, только скопировал его откуда-то еще.Это не достаточно хорошо для меня, я хочу понять, что здесь происходит.

Если у нас будет что-то вроде:

(test1, test2, test3="3", test4="4")

В результате будет test1 == "3", test2 == "4",test3 == nil и test4 == "4".Я понимаю, почему это происходит, но если мы сделаем что-то вроде:

(test1, test2, test3="3", test4="4", test5 = "5", test6 = "6")

, теперь результат будет test1 == "3", test2 == "4", test3 == "5", test4 == "4", test5 == "5", test6 == "6".

Почему не test5 == nil?

Ответы [ 3 ]

3 голосов
/ 18 июня 2010

Похоже, что это выполняется так:

(test1, test2, test3) = ("3"), (test4 = "4"), (test5 = "5"), (test6 = "6")

# Equivalent:
test1 = "3"
test2 = test4 = "4"
test3 = test5 = "5"
      ; test6 = "6"
2 голосов
/ 18 июня 2010

Оператор присваивания возвращает RHS (правая часть выражения), поэтому a = b = 4 устанавливает для a и b значение 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)

Учитывая это,а также тот факт, что Ruby допускает несколько назначений в одном операторе, ваше утверждение может быть переписано (Ruby видит запятые и знак равенства и считает, что вы пытаетесь выполнить несколько назначений, причем первое равенство разделяет LHS (слева)стороны) и RHS):

test1, test2, test3="3", test4="4", test5 = "5", test6 = "6"
-> test1, test2, test3 = "3", (test4 = "4"), (test5 = "5"), (test6 = "6")

RHS оценивается первым, что оставляет нам:

test1, test2, test3 = "3", "4", "5", "6"

с побочным эффектом установки test4 в "4",test5 до "5" и test6 до "6".

Затем LHS оценивается и может быть переписан как:

test1 = "3"
test2 = "4"
test3 = "5"
// since there are 3 items on the LHS and 4 on the RHS, nothing is assigned to "6"

Таким образом, в концеоператор, шесть переменных будут установлены:

test1 == "3"
test2 == "4"
test3 == "5"
test4 == "4"
test5 == "5"
test6 == "6"
1 голос
/ 18 июня 2010

Когда я запускаю ваш второй пример:

(test1, test2, test3="3", test4="4", test5 = "5", test6 = "6")

Я получаю результат, отличный от того, что вы сообщаете:

test1=="3", test2=="4", test3=="5", test4=="4", test5=="5", test6=="6"

(обратите внимание, что test4 это "4", а не "6")

Что имеет смысл для меня, потому что оно разбирает вот так:

((test1, test2, test3) = ("3", (test4="4", (test5 = "5", (test6 = "6")))))

Итак, вы получите оценку примерно так:

((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]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...