2012-12-22 12 views
5

Say mam klasę Player i chcę metoda logiczna, aby sprawdzić, czy gracz jest atakowany:Używanie znaku zapytania w metodach rubinowe

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

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

pojawia się błąd składni:

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

Usuwanie znak zapytania z attacked rozwiązuje problem, ale pomyślałem, że lepiej będzie przestrzegać konwencji, aby w moim kodzie był attacked?. To nie jest wielka sprawa, aby zrezygnować ze znaku zapytania, ale dlaczego konwencje zero? ii są nieprawidłowe?

+0

'@ attacked' jest zmienną instancji, a nie metodą. '@attacked = false'; ... "zaatakowano def?"; @zaatakowany; end' –

+3

Domyślam się, że nie możesz mieć znaku zapytania jako części nazwy zmiennej. To tylko dla metod. Ponadto nie pamiętam metody pojedynczego znaku zapytania z ustawiaczem. Wszystkie są gettery. –

+0

To dobra uwaga. Wszystkie są gettery. Stworzenie setera ze znakiem zapytania tworzy metodę "attacked? =", Która jest również nieprawidłową składnią. Tak więc mój kod miałby niepoprawną nazwę zmiennej i niepoprawną nazwę metody. – rubyuser1357796

Odpowiedz

11

Zauważ, że jeśli wykomentuj linię powodując błąd (@attacked? = false), nadal pojawia się błąd odnoszący się do znaku zapytania:

NameError: invalid attribute name `attacked?' 

Problemem jest to, że ? nie jest ważny znak w nazwa zmiennej. Pierwszy błąd (SyntaxError, który widzisz) jest wywoływany w czasie analizy i natychmiastowy. Drugi błąd powstaje, gdy Ruby próbuje ocenić kod i nie może utworzyć zmiennej instancji o nazwie zawierającej nieprawidłowy znak.

Znak zapytania jest ważna postać w końcu metoda nazwy chociaż (w rzeczywistości jest to możliwe, aby mieć metodę z ? gdziekolwiek w jego imieniu, ale nie można nazwać taką metodę bezpośrednio) .

Jednym ze sposobów osiągnięcia tego, co chcesz, jest coś takiego:

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

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

Pozostawia attacked bez znaku zapytania, ale dodaje attacked? jako alias.

+0

Dzięki! Nawet nie myślałem o używaniu pseudonimu. – rubyuser1357796

3

Wystąpiłem już wcześniej w tym samym problemie i żałowałem, że nie mogę utworzyć zmiennych instancji z końcowym znakiem zapytania. Wydaje się, że jest to kwestia podstawowa w gramatyce Rubiego. Sprawdź to:

>> 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 

Więc ? symbol jest przeciążony w gramatyce Ruby - służy do potrójnego operatora i jako część ważnych identyfikatorów nazw metod. Powoduje to niejednoznaczność w ostatnim przypadku, w którym lexer Ruby wydaje się odgryźć a? jako pojedynczy token, co sprawia, że ​​nie jest w stanie poprawnie parsować reszty operatora trójskładnikowego. W przypadku zmiennych instancji nie może się to zdarzyć.

Ponownie, zgadzam się, że dopuszczenie znaków zapytania w nazwach instancji byłoby bardzo użyteczne, z pewnością bardziej wartościowe niż pewne niejasne użycie operatora trójskładnikowego.

Powiązane problemy