2010-10-25 15 views
25

Ci scusiamo per questo, probabilmente, domanda davvero newbie:attr_reader con il punto interrogativo in un nome

voglio definire un getter che restituisce il valore bool. fi:

attr_reader :server_error? 

Ma allora, come faccio aggiorno, come Rubino (1,9) genera errore di sintassi se c'è un punto di domanda alla fine:

#unexpected '=' 
@server_error? = true 
self.server_error? = true 

risposta

9

Suggerisco definire un proprio metodo piuttosto che usare :attr_reader

def server_error? 
    [email protected]_error # Or any other idiom that you generally use for checking boolean 
end 

per brevità, si potrebbe fare in una sola riga:

def server_error?; [email protected]_error; end 
2

attr_reader è un esempio di ciò che "Metaprogrammazione Ruby" definisce una "Classe Macro". Se si voleva, si potrebbe definire la propria macro di classe, in modo tale che si potrebbe fare

Class SampleClass 
    my_boolean_reader :server_error 

    def initialize 
    @server_error = false 
    end 
end 

sample_object = SampleClass.new 
sample_object.server_error? # => false 
+0

Ciao, e grazie per la tua risposta. Che cosa è esattamente my_boolean_reader qui? Ho ottenuto NoMethodError, quindi ovviamente mi manca qualcosa. – Ernest

+4

@ c64ification: Ho detto si potrebbe definire un metodo chiamato 'my_boolean_reader' che avrei fatto quello che cercavamo. –

+0

ok, che è interessante, grazie – Ernest

29

Questa domanda è vecchia, ma con alias_method è possibile ottenere che:

class Foo 
    attr_reader :server_error 
    alias_method :server_error?, :server_error 

    # [...] 
end 

In sostanza il metodo server_error? sarà un alias per il metodo server_error.

+0

bella punta, grazie per l'aggiunta di esso :) – Ernest

3

Se è necessario definire tali metodi più volte, definire un modulo nome AttrBoolean:

module AttrBoolean 
    def self.included(base) 
    base.extend ClassMethods 
    end 

    module ClassMethods 
    def attr_boolean(*names) 
     names.each do |name| 
     define_method(:"#{name}=") do |value| 
      instance_variable_set(:"@#{name}", value) 
     end 

     define_method(:"#{name}?") do 
      !!instance_variable_get(:"@#{name}") 
     end 
     end 
    end 
    end 
end 

È possibile utilizzare questo nel modo seguente:

class Foo 
    include AttrBoolean 

    attr_boolean :server_error, :resolved 
end 

f = Foo.new 
f.server_error = true 
f.resolved = false 
f.server_error? # => true 
f.resolved?  # => false 

Nota che i metodi getter senza domanda il marchio non è definito. L'espressione f.server_error genera un'eccezione.

Problemi correlati