在ruby方法中使用问号

时间:2012-12-22 19:46:58

标签: ruby syntax methods

假设我有类Player并且我想要一个布尔方法来检查玩家是否受到攻击:

class Player
  attr_accessor :name, :health, :attacked?

  def initialize(name)
    @name = name
    @health = 100
    @attacked? = false
  end
end

我收到语法错误:

SyntaxError: (irb):14: syntax error, unexpected '='
@attacked? = false
            ^
        from /usr/bin/irb:12:in `<main>'

attacked中删除问号可以解决问题,但我认为在我的代码中使用attacked?更符合惯例。放弃问号并不是什么大不了的事,但为什么zero?nil?约会时@variables?def methods?=约定无效?

2 个答案:

答案 0 :(得分:12)

请注意,如果您注释掉导致错误的行(@attacked? = false),您仍会收到与问号相关的错误:

NameError: invalid attribute name `attacked?'

问题是?不是变量名中的有效字符。第一个错误(您看到的SyntaxError)是在解析时引起的并立即捕获。当Ruby尝试评估代码并且无法创建名称包含无效字符的实例变量时,会导致第二个错误。

问号 方法名称末尾的有效字符(实际上可以在其中的任何位置使用?的方法名称,但你不能直接调用这样的方法。)

实现目标的一种方法是:

class Player
  attr_accessor :name, :health, :attacked
  alias :attacked? :attacked

  def initialize(name)
    @name = name
    @health = 100
    @attacked = false
  end
end

这会使attacked没有问号,但会将attacked?添加为别名。

答案 1 :(得分:3)

之前我遇到过同样的问题,并希望我可以使用尾随问号制作实例变量。这似乎是Ruby语法中的一个极端情况。看看这个:

>> 1 ? 2 : 3
=> 2
>> 1?2:3
=> 2
>> @a = true
=> true
>> @a?1:2
=> 1
>> a = true
=> true
>> a ? 1 : 2
=> 1
>> a?1:2
SyntaxError: (irb):9: syntax error, unexpected ':', expecting $end

因此,?符号在Ruby的语法中被重载 - 它用于三元运算符,作为方法名称的有效标识符的一部分。这导致了最后一种情况的模糊性,其中Ruby的词法分析器似乎将a?作为单个标记咬掉,这使得它无法正确解析其余的三元运算符。使用实例变量,这不可能发生。

同样,我同意允许实例变量名称中的问号非常有用,当然比使三元运算符的一些模糊用法更加有价值。