Ruby: convención y uso de nomenclatura de atributos booleanos
attributes conventions (5)
? es una convención para nombres de métodos, no variables. No puede usar una variable de instancia llamada @foo?
Sin embargo, podría usar una variable llamada @foo
y nombrar el método getter (creado manualmente) foo?
Si quieres.
Aprendiendo ruby. Tengo la impresión de que los atributos booleanos deben nombrarse de la siguiente manera:
my_boolean_attribute?
Sin embargo, obtengo errores de sintaxis cuando intento hacer lo siguiente:
class MyClass
attr_accessor :my_boolean_attribute?
def initialize
:my_boolean_attribute? = false
end
end
Aparentemente, el rubí odia el "?". ¿Es esta la convención? ¿Qué estoy haciendo mal?
El símbolo attr_accessor
implica que el nombre de la variable es @my_boolean_attribute
, así que eso es lo que debería establecer (no el símbolo).
Además, no puedes usar? para variables, solo nombres de métodos.
La forma más fácil de agregar rápidamente un "método de pregunta" es usar aliasing para su método de lector
class Foo
attr_accessor :dead
alias_method :dead?, :dead # will pick up the reader method
end
Metaprogramación de parches de mono - tal vez se puede hacer más elegante, esto es solo un borrador rápido, y no he hecho metaprogramación por un tiempo ...
# inject the convenience method into the definition of the Object class
class Object
def Object::bool_attr(attrname)
class_eval { define_method(attrname.to_s,
lambda { instance_variable_get(''@'' + attrname.to_s.chop) }) }
class_eval { define_method(attrname.to_s.chop+"=",
lambda { |x| instance_variable_set(''@''+attrname.to_s.chop, x) }) }
end
end
### somewhere later
class MyClass
bool_attr :my_boolean_attribute?
def initialize
@my_boolean_attribute = true
end
end
# yet even more later
foo = MyClass.new
bar = MyClass.new
foo.my_boolean_attribute = 1
puts foo.my_boolean_attribute?
puts bar.my_boolean_attribute?
Con este enfoque, puede ser SECO y obtener el buen questionmark también. Es posible que necesite elegir un nombre mejor que " bool_attr ", como " bool_attr_accessor " o algo similar.
Las definiciones que hice son un poco irritables, en un sentido que el signo de interrogación está presente en el símbolo original. Probablemente, un enfoque más limpio sería evitar el signo de interrogación en el nombre del símbolo y anexarlo durante la definición del método; debería ser menos confuso.
Ah, y casi se olvidó de incluir el enlace obligatorio: Ver metaclases claramente
Editar: tres años después; los tiempos están cambiando''…
La respuesta de Julik es la forma más simple y mejor para abordar el problema en estos días:
class Foo
attr_accessor :dead
alias_method :dead?, :dead # will pick up the reader method
end
Mi respuesta a la pregunta original sigue, para la posteridad ...
La versión corta:
No puede usar un signo de interrogación en el nombre de una variable de instancia.
La versión más larga:
Tomemos, por ejemplo, attr_accessor :foo
- es simplemente conceptualmente un poco de azúcar sintáctico para lo siguiente:
def foo
@foo
end
def foo=(newfoo)
@foo = newfoo
end
Además, el sufijo de interrogación es básicamente una convención para indicar que el valor de retorno de un método es booleano.
La mejor aproximación que puedo hacer de lo que estás buscando aquí ...
class MyClass
def initialize
@awesome = true
end
def awesome?
@awesome
end
end
En este caso, puede haber un caso para usar attr_accessor
; después de todo, puede ser explícito que está trabajando directamente con un atributo booleano. En general, guardo el sufijo de interrogación para cuando estoy implementando un método cuyo valor de retorno booleano se basa en condiciones ligeramente más complejas que solo el valor de un atributo.
¡Aclamaciones!
Editar, dos años después, después de un comentario reciente:
- Ruby aplica ciertas convenciones de nombres.
Los símbolos en Ruby no pueden tener signos de interrogación. Por lo tanto, invocaciones deEditar: no es correcto, solo usa la sintaxis citada para un símbolo, por ejemplo:my_boolean_attribute?
ambos fallarán con unNameError
.:"my_attribute?"
- Los símbolos son inmutables, el intento de asignar a uno arrojará un
SyntaxError
.