Операторы и закрепление Ruby Case не работают с attr_reader

Этот код работает:

class Hello
  def initialize
    @name = "Paul"
  end

  def say_name(maybe_name)
    name = self.name
    case maybe_name
    in ^name
      puts "Hello, Paul!"
    else
      puts "No match"
    end
  end

  private

  attr_reader :name
end

Hello.new.say_name("Paul") # "Hello, Paul!"

Однако если я удалю name = self.name, я получу имя без локальной переменной для закрепленной переменной.

Это ошибка в Ruby или намерение? Я полагаю, это работает только с локальными переменными? Если я удалю эту строку, name внутри метода say_hello станет нулевым, но он определен.

попробуй in ^(name)

Sergio Tulentsev 04.04.2024 13:45
Пошаговое руководство по созданию собственного Slackbot: От установки до развертывания
Пошаговое руководство по созданию собственного Slackbot: От установки до развертывания
Шаг 1: Создание приложения Slack Чтобы создать Slackbot, вам необходимо создать приложение Slack. Войдите в свою учетную запись Slack и перейдите на...
1
1
79
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Это ошибка в Ruby или намерение?

Эта конкретная ошибка является преднамеренной. При ссылке на несуществующую локальную переменную вы получаете исключение.

Я полагаю, это работает только с локальными переменными?

Он работает с любым типом переменных, как указано в документации : «вы также можете закрепить переменные экземпляра, глобальные переменные и переменные класса». Однако простой синтаксис ^variable не работает с методами. Чтобы ваш код работал, вам нужно либо напрямую ссылаться на переменную экземпляра @name:

case maybe_name
in ^@name
  # ...
end

или используйте синтаксис ^(expression), который позволяет «закрепить результат произвольных выражений с помощью круглых скобок»: (при этом «произвольное выражение» является вызовом метода)

case maybe_name
in ^(name)
  # ...
end

Он работает с произвольными выражениями. Просто нужно заключить в круглые скобки.

Sergio Tulentsev 04.04.2024 13:46

Ах, это не работает с методами, вот что меня смутило. Полагаю, я привык считать методы и переменные взаимозаменяемыми в Ruby, поскольку мы не думаем о типах так много, как в других языках.

Paul Byrne 04.04.2024 13:48

Честно говоря, я не понимаю, почему для закрепления вообще нужны круглые скобки, чтобы можно было использовать произвольные выражения. ^expression мне кажется, все в порядке, но, вероятно, у них были свои причины ;)

Stefan 04.04.2024 14:01

@Stefan Стефан Я предполагаю, что это из-за таких вещей, как операторы, вызовы связанных методов, вызовы методов с аргументами и т. д. Например, я согласен, я не возражаю ^expression, но следующие менее привлекательны ^1 + 1, ^expression.downcase, ^expression.select {|i| i < some_calculation}. В этих случаях явные круглые скобки не только дифференцируют логику, но и почти наверняка делают синтаксический анализатор более рациональным.

engineersmnky 04.04.2024 21:52

@engineersmnky, безусловно, есть (много) случаев использования скобок. Я просто удивлен, что простой ^name не просто оценивает name. Ограничивать этот поиск только переменными, мне кажется, не имеет особого смысла.

Stefan 05.04.2024 10:34

Другие вопросы по теме