Rubino: attributo booleano convenzione di denominazione e l'uso
-
13-09-2019 - |
Domanda
L'apprendimento rubino. Sono sotto l'impressione che gli attributi booleani devono essere nominati nel seguente modo:
my_boolean_attribute?
Tuttavia, ottengo errori di sintassi quando si tenta di effettuare le seguenti operazioni:
class MyClass
attr_accessor :my_boolean_attribute?
def initialize
:my_boolean_attribute? = false
end
end
A quanto pare rubino odia il "?". E 'questa la Convenzione? Che cosa sto facendo di sbagliato?
Soluzione
Modifica: tre anni più tardi; i tempi, che sono a-changin' ...
di Julik risposta è il modo più semplice e migliore per affrontare il problema in questi giorni:
class Foo
attr_accessor :dead
alias_method :dead?, :dead # will pick up the reader method
end
La mia risposta alla domanda iniziale segue, per i posteri ...
La versione corta:
Non è possibile utilizzare un punto di domanda in nome di una variabile di istanza.
La versione più lunga:
Si prenda, per esempio, attr_accessor :foo
- è semplicemente concettualmente un po 'di zucchero sintattico per i seguenti:
def foo
@foo
end
def foo=(newfoo)
@foo = newfoo
end
Inoltre, il suffisso punto interrogativo è per lo più solo una convenzione per indicare che il valore di ritorno di un metodo è un valore booleano.
La migliore approssimazione che posso fare di ciò che si sta andando per qui ...
class MyClass
def initialize
@awesome = true
end
def awesome?
@awesome
end
end
In questo caso, ci può essere un caso da effettuare per l'utilizzo di attr_accessor
- dopo tutto, può essere esplicito che si sta lavorando direttamente con un attributo booleano. In generale, risparmio il suffisso punto interrogativo per quando io sono l'attuazione di un metodo il cui valore booleano di ritorno valore si basa su condizioni leggermente più complesse del semplice valore di un attributo.
Cheers!
Modifica, due anni più tardi, dopo un recente commento:
- Rubino fa rispettare certe convenzioni di denominazione.
Simboli in Ruby non possono avere punti di domanda. Così invocazioni diEdit:. Non è corretta, basta usare la sintassi citato per un simbolo, per esempio,:my_boolean_attribute?
sia non riuscirà con unNameError
:"my_attribute?"
- I simboli sono immutabili, il tentativo di assegnare ad uno lancerà un
SyntaxError
.
Altri suggerimenti
Il modo più semplice per aggiungere rapidamente un "metodo di domanda" è quello di utilizzare aliasing per il metodo lettore
class Foo
attr_accessor :dead
alias_method :dead?, :dead # will pick up the reader method
end
Il simbolo attr_accessor
implica che il nome della variabile è @my_boolean_attribute
, ed è quello che si dovrebbe essere imposta (non il simbolo).
Inoltre, non è possibile utilizzare? per le variabili, i nomi solo di metodo.
? è convenzione per methodnames, non variabili. Non è possibile utilizzare un @foo?
variabile di istanza denominata, tuttavia è possibile utilizzare un @foo
variabile chiamata e il nome del (creata manualmente) getter metodo foo?
se si voleva.
scimmia-patching metaprogrammazione - forse può essere reso più elegante, questo è solo un rapido progetto, e non ho fatto metaprogrammazione per un po '...
# 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 questo approccio, si può essere secco e ottenere il bel punto interrogativo troppo. Devi solo potrebbe essere necessario scegliere un nome migliore di " bool_attr ", come, " bool_attr_accessor " o qualcosa di simile.
Le definizioni che ho fatto sono un po 'irritabile, in un certo senso che il punto interrogativo è presente nel simbolo originale. Probabilmente un approccio più pulito sarebbe quello di evitare il punto interrogativo nel nome del simbolo e aggiungerlo durante la definizione del metodo -. Dovrebbe essere meno confusione
Oh, e quasi dimenticato di includere il link obbligatorio: Vedendo metaclassi chiaramente