Как я могу исправить эту синтаксическую ошибку Ruby относительно конечного ключевого слова? - PullRequest
1 голос
/ 11 октября 2019

Это из задачи по упражнениям. Создание каждого решения до сих пор методом класса кажется странным способом достижения цели, но это не моя идея. В любом случае вот код:

class ResistorColorDuo
  @@colors = %w(
    black
    brown
    red
    orange
    yellow
    green
    blue
    violet
    grey
    white)

  def self.value(array)
    @@colors.index array[0] * 10 + @@colors.index array[1]
  end
end

Сообщение об ошибке:

Traceback (most recent call last):
    1: from resistor_color_duo_test.rb:2:in `<main>'
resistor_color_duo_test.rb:2:in `require_relative': /home/muhammad/exercism/ruby/resistor-color-duo/resistor_color_duo.rb:15: syntax error, unexpected tIDENTIFIER, expecting keyword_end (SyntaxError)
...0]) * 10 + @@colors.index array[1]

Я не вижу проблемы, потому что все ключевые слова end правильно сбалансированы. Как мне исправить это?

Ответы [ 2 ]

3 голосов
/ 12 октября 2019

У меня сложилось впечатление, что скобки в данном случае необязательны.

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

Если Ruby обнаружит пробел сразу послеметод, он будет анализировать остальную часть строки в качестве аргумента (ов). Таким образом, круглые скобки являются необязательными, если в строке нет ничего, что не является частью аргумента метода. Если вы это сделаете, вы должны указать, какая часть строки составляет ваш список аргументов, заключив его в скобки.

Вот потенциальная проблема, о которой следует знать. Рассмотрим эти строки, которые отличаются только одним пробелом:

f(3+2)+1
f (3+2)+1

Первый из них передает 5 функции f и добавляет 1 к результату. Второй передает 6 в функцию f. По той же причине: если Ruby встречает пробел сразу после вызова метода, остальная часть строки анализируется как список аргументов.

Я заимствовал этот пример из книги Матца, где он красноречиво называет это «пагубным»зависимость от пробелов. "Вы должны быть осторожны с пробелами в строках вызова методов.

Это также является причиной ошибки, которую вы получаете. Ruby не может проанализировать вашу строку, потому что у вас есть два вызова метода. Таким образом, второе вызывает ошибку: Ruby ожидает ключевое слово end и вместо этого сталкивается с другим вызовом метода.

Добавление скобок ко второму избавит от синтаксической ошибки:

@@colors.index array[0] * 10 + @@colors.index(array[1])

Но, вероятно, она не даст желаемого результата. Это будет проанализировано так:

@@colors.index(array[0] * 10 + @@colors.index(array[1]))

Итак, используйте скобки для них обоих. Я не уверен, что вы пытаетесь сделать (не уверен, что вы хотите умножить на 10), но что-то вроде этого:

@@colors.index(array[0]) * 10 + @@colors.index(array[1])

В общем, я предпочитаю заключать в скобки аргументы для вызовов методов. Практически единственный раз, когда я их не использую, это puts, print и p (правка: и все те, что я забыл об этом, добавил Йорг в комментариях ниже).

И будьте осторожны, чтобы не поставить пробел между вызовом метода и открытым пареном.

2 голосов
/ 12 октября 2019

Дополнение к ответу @dinjas из секции комментариев

Если у вас есть два массива:

colors = [1,10]
array = [1]

И сделайте что-то похожее в вашем примере:

colors.index array[0] * 10

вы получите #=> 1, индекс второго элемента массива colors, равный 10. Это потому, что Ruby сначала вычислит array[0] * 10 (то есть 1 * 10 = 10), а затем проверит индекс первого элемента, равного 10 в массиве colors.

Если вы, однако,добавьте скобки и сделайте следующее:

 colors.index(array[0]) * 10

вы получите #=> 0, потому что индекс первого элемента, равного 1 (array[0] = 1) в массиве colors, равен 0 и 0 * 10 = 0.

Несколько дней назад была также похожая проблема, вы можете проверить ее здесь .

...