A *
означает «все остальные параметры»._
- это просто другое имя переменной, хотя оно немного особенное.Таким образом, они отличаются, например, следующее не имеет смысла:
[[1, 2, 3], [4, 5, 6]].each{|*, x, *| p x} # Syntax error
Действительно, как Руби должна знать, должна ли первая звезда получить 0, 1 или 2 из значений (и наоборот)?
Очень мало случаев, когда вы хотите использовать звезду для игнорирования параметров.Примером может быть, если вы хотите использовать только последний из переменного числа параметров:
[[1], [2, 3], [4, 5, 6]].each{|*, last| p last} # => prints 1, 3 and 6
Ruby позволяет вам не давать имя «остальным» параметрам, но вы можете использовать _
:
[[1], [2, 3], [4, 5, 6]].each{|*_, last| p last} # => prints 1, 3 and 6
Как правило, число параметров известно, и ваш лучший выбор - использовать _
:
[[1, 2, 3], [4, 5, 6]].each{|_, mid, _| p mid} # prints 2 and 5
Обратите внимание, что вы можете оставить последний параметр без именитоже (как вы можете при использовании *
), хотя это менее очевидно:
[[1, 2, 3], [4, 5, 6]].each{|_, mid, | p mid} # prints 2 and 5
Теперь _
- это назначенное имя переменной, которое нужно использовать, когда вы нехочу использовать значение.Это специальное имя переменной по двум причинам:
- Ruby не будет жаловаться, если вы его не используете (если включены предупреждения)
- Ruby позволит вам повторить егов списке аргументов.
Пример точки 1:
> ruby -w -e "def foo; x = 42; end; foo"
-e:1: warning: assigned but unused variable - x
> ruby -w -e "def foo; _ = 42; end; foo"
no warning
Пример точки 2:
[[1, 2, 3], [4, 5, 6]].each{|unused, mid, unused| p mid}
# => SyntaxError: (irb):23: duplicated argument name
[[1, 2, 3], [4, 5, 6]].each{|_, mid, _| p mid}
# => prints 2 and 5
Наконец, как отмечает @DigitalRoss, _
содержит последний результат в irb
Обновление : в Ruby 2.0 вы можете использовать любую переменную, начинающуюся с _
, чтобы указать, что она не используется.Таким образом, имя переменной может быть более явным в отношении того, что игнорируется:
_scheme, _domain, port, _url = parse_some_url
# ... do something with port