Этот код работает:
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
станет нулевым, но он определен.
Это ошибка в Ruby или намерение?
Эта конкретная ошибка является преднамеренной. При ссылке на несуществующую локальную переменную вы получаете исключение.
Я полагаю, это работает только с локальными переменными?
Он работает с любым типом переменных, как указано в документации : «вы также можете закрепить переменные экземпляра, глобальные переменные и переменные класса». Однако простой синтаксис ^variable
не работает с методами. Чтобы ваш код работал, вам нужно либо напрямую ссылаться на переменную экземпляра @name
:
case maybe_name
in ^@name
# ...
end
или используйте синтаксис ^(expression)
, который позволяет «закрепить результат произвольных выражений с помощью круглых скобок»: (при этом «произвольное выражение» является вызовом метода)
case maybe_name
in ^(name)
# ...
end
Он работает с произвольными выражениями. Просто нужно заключить в круглые скобки.
Ах, это не работает с методами, вот что меня смутило. Полагаю, я привык считать методы и переменные взаимозаменяемыми в Ruby, поскольку мы не думаем о типах так много, как в других языках.
Честно говоря, я не понимаю, почему для закрепления вообще нужны круглые скобки, чтобы можно было использовать произвольные выражения. ^expression
мне кажется, все в порядке, но, вероятно, у них были свои причины ;)
@Stefan Стефан Я предполагаю, что это из-за таких вещей, как операторы, вызовы связанных методов, вызовы методов с аргументами и т. д. Например, я согласен, я не возражаю ^expression
, но следующие менее привлекательны ^1 + 1
, ^expression.downcase
, ^expression.select {|i| i < some_calculation}
. В этих случаях явные круглые скобки не только дифференцируют логику, но и почти наверняка делают синтаксический анализатор более рациональным.
@engineersmnky, безусловно, есть (много) случаев использования скобок. Я просто удивлен, что простой ^name
не просто оценивает name
. Ограничивать этот поиск только переменными, мне кажется, не имеет особого смысла.
попробуй
in ^(name)