Ruby: Как убрать предупреждение: `*' интерпретируется как префикс аргумента?

Как я могу удалить "предупреждение: `*' интерпретируется как префикс аргумента" из следующего кода?

hash = {"a" => 1,
        "b" => 2,
        "s" => 3,}

if "string".start_with? *hash.keys then
  puts "ok"
else
  puts "ng"
end

Когда я запускаю код выше, я получаю:

$ ruby -w /tmp/a.rb
/tmp/a.rb:5: warning: `*' interpreted as argument prefix
ok

Как лучше всего исправить это предупреждение?

Я попытался поставить скобки вокруг hash следующим образом:

hash = {"a" => 1,
        "b" => 2,
        "s" => 3,}

if "string".start_with? (*hash.keys) then
  puts "ok"
else
  puts "ng"
end

тогда вы получите:

$ ruby -w /tmp/a.rb
/tmp/a.rb:5: syntax error, unexpected *
if "string".start_with? (*hash.keys) then
                          ^
/tmp/a.rb:5: syntax error, unexpected ')', expecting '='
if "string".start_with? (*hash.keys) then
                                    ^
/tmp/a.rb:7: syntax error, unexpected keyword_else, expecting end-of-input

И это проблема, описанная в разделе Почему пробелы влияют на вызовы рубиновых функций?, и явно не способ исправить предупреждение, которое я пытаюсь исправить.

Моя рубиновая версия:

$ ruby --version
ruby 2.3.3p222 (2016-11-21) [x86_64-linux-gnu]

person Yasushi Shoji    schedule 24.01.2017    source источник
comment
@AlexGolubenko, этот вопрос касается предупреждения о префиксе аргумента, а не пробела между именем функции и скобкой.   -  person Yasushi Shoji    schedule 24.01.2017
comment
Я согласен с Яшуши. Основной способ, которым люди находят ответы на вопросы о переполнении стека, — это гуглить предупреждение. Если у них есть эта проблема, они не будут why does white space affect ruby function calls гуглить, потому что это будет означать, что они уже знают, что вызывает предупреждение. Я думаю, что дубликат тега должен быть удален.   -  person Obromios    schedule 31.10.2019


Ответы (1)


Если вы собираетесь использовать круглые скобки для вызова метода, вы должны не ставить пробел между именем метода и открывающими скобками:

if "string".start_with?(*hash.keys)
  puts "ok"
else
  puts "ng"
end

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

Как только вы добавите круглые скобки, вызывающие метод, вы удалите любой возможный намек на двусмысленность в отношении того, что должен означать ваш *, и предупреждение должно исчезнуть.


Кстати, предупреждение, которое вы получаете в этом случае, довольно, гм, глупо. Если подумать, предупреждение не так глупо, потому что Ruby может быть чувствительным к пробелам неожиданным образом. Этот:

o.m *x

можно интерпретировать как:

o.m(*x)

or as:

o.m() * x

но эти:

o.m * x
o.m*x
o.m* x

можно интерпретировать одинаково. Конечно, все три из них интерпретируются как o.m() * x, и только o.m *x воспринимается как o.m(*x). Разумное использование пробелов предполагает, что o.m *x очевидно представляет собой знак, тогда как o.m * x очевидно является умножением, но пара дней на SO должна убедить вас в том, что использование пробелов вряд ли является разумным или последовательным.

Тем не менее, вывод -w в реальном мире имеет тенденцию быть настолько объемным и шумным, что -w почти бесполезен.

person mu is too short    schedule 24.01.2017