2010-10-25 8 views
25

Lo siento por esto, probablemente, pregunta realmente novato:attr_reader con signo de interrogación en un nombre

Quiero definir un captador que devuelve el valor bool. fi:

attr_reader :server_error? 

Pero entonces, ¿cómo actualizo, como Ruby (1.9) lanza error de sintaxis si hay un signo de interrogación al final:

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

Respuesta

9

Sugiero definir su propio método bastante que el uso de :attr_reader

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

por el bien de la brevedad, usted podría hacerlo en una sola línea:

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

attr_reader es un ejemplo de lo que "Metaprogramación Ruby" llama una "Clase Macro". Si quisiera, podría definir su propio macro clase, de tal manera que se podría hacer

Class SampleClass 
    my_boolean_reader :server_error 

    def initialize 
    @server_error = false 
    end 
end 

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

Hola, y gracias por su respuesta. ¿Qué es exactamente my_boolean_reader aquí? Obtuve NoMethodError, así que obviamente me falta algo. – Ernest

+4

@ c64ification: Dije que podrías definir un método llamado 'my_boolean_reader' que haría lo que estabas buscando. –

+0

ok, eso es interesante, gracias – Ernest

29

Esta pregunta es viejo pero con alias_method se puede lograr que:

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

    # [...] 
end 

Básicamente el método server_error? será un alias para el método server_error.

+0

Buen consejo, gracias por agregarlo :) – Ernest

3

Si es necesario definir dichos métodos en varias ocasiones, definir un módulo llamado 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 

Puede utilizar esta de la siguiente manera:

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 

Tenga en cuenta que los métodos getter sin pregunta marca no están definidos. La expresión f.server_error arroja una excepción.

Cuestiones relacionadas