5

クラスが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?=

4

2 に答える 2

13

エラーの原因となっている行 ( ) をコメントアウトして@attacked? = falseも、疑問符に関連するエラーが表示されることに注意してください。

NameError: invalid attribute name `attacked?'

問題は?、変数名に有効な文字ではないことです。最初のエラー (表示SyntaxErrorされている) は解析時に発生し、すぐに検出されます。2 番目のエラーは、Ruby がコードを評価しようとして、無効な文字を含む名前のインスタンス変数を作成できない場合に発生します。

ただし、疑問符メソッド名の末尾にある有効な文字です (実際には?、名前のどこにでもメソッドを含めることができますが、そのようなメソッドを直接呼び出すことはできません)。

あなたが望むものを達成する1つの方法は、次のようなものです:

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

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

これによりattacked、疑問符がなくなりますattacked?が、エイリアスとして追加されます。

于 2012-12-22T20:37:26.690 に答える
4

以前に同じ問題に遭遇したことがあり、インスタンス変数の末尾に疑問符を付けたいと思っていました。これは、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?、単一のトークンとして を噛み砕くように見え、残りの三項演算子を適切に解析できなくなります。インスタンス変数では、これは起こりません。

繰り返しになりますが、インスタンス変数名に疑問符を使用できるようにすることは非常に便利であり、三項演算子のあいまいな使用をあいまいにしないようにするよりも確かに価値があることに同意します。

于 2012-12-22T20:06:50.057 に答える