Ruby: Boolean Attribut Namenskonvention und Verwendung
-
13-09-2019 - |
Frage
Lernen Rubin. Ich habe den Eindruck, dass boolean Attribute genannt werden sollen, wie folgt:
my_boolean_attribute?
Allerdings erhalte ich Fehler Syntax, wenn folgendes zu tun versuchen:
class MyClass
attr_accessor :my_boolean_attribute?
def initialize
:my_boolean_attribute? = false
end
end
Offenbar Rubin hasst das „?“. Ist dies die Konvention? Was mache ich falsch?
Lösung
Edit: drei Jahre später; die Zeiten, sie sind a-changin' ...
Julik Antwort ist die einfachste und beste Weg, um das Problem in diesen Tagen zu bewältigen:
class Foo
attr_accessor :dead
alias_method :dead?, :dead # will pick up the reader method
end
Meine Antwort auf die ursprüngliche Frage folgt, für die Nachwelt ...
Die Kurzversion:
Sie können nicht ein Fragezeichen im Namen einer Instanzvariablen verwendet werden.
Die längere Version:
Nehmen wir zum Beispiel, attr_accessor :foo
- es ist einfach konzeptionell ein bisschen syntaktischer Zucker für die folgenden:
def foo
@foo
end
def foo=(newfoo)
@foo = newfoo
end
Darüber hinaus ist die Fragezeichen Suffix meist nur eine Konvention, um anzuzeigen, dass der Rückgabewert einer Methode ist ein boolean.
Die beste Annäherung ich machen kann, was Sie hier gehen ...
class MyClass
def initialize
@awesome = true
end
def awesome?
@awesome
end
end
In diesem Fall kann es ein Fall geben gemacht werden attr_accessor
für die Verwendung - direkt mit einem boolean-Attribute nach allem, es explizit sein, dass Sie arbeiten. Im Allgemeinen ich die Fragezeichen-Suffix für speichern, wenn ich eine Methode, deren boolean Rückgabewert am Implementierung basiert auf etwas komplexeren Bedingungen als nur den Wert eines Attributs.
Cheers!
Bearbeiten, zwei Jahre später, nach einer letzten Bemerkung:
- erzwingt Rubin bestimmte Namenskonventionen.
Symbole in Ruby kann keine Fragezeichen haben. So Anrufungen vonEdit:. Nicht richtig, nur die zitierte Syntax für ein Symbol verwenden, zum Beispiel:my_boolean_attribute?
beide werden mit einemNameError
scheitern:"my_attribute?"
- Symbole sind unveränderlich, versuchen, eine zuweisen eine
SyntaxError
werfen.
Andere Tipps
Der einfachste Weg, um schnell eine „Frage-Methode“ add ist Aliasing für Ihre Leser Methode zu verwenden,
class Foo
attr_accessor :dead
alias_method :dead?, :dead # will pick up the reader method
end
Das attr_accessor
Symbol bedeutet, dass der Variablenname ist @my_boolean_attribute
, so dass das, was ist, sollten Sie (nicht auf das Symbol) werden zu setzen.
Sie können aber auch nicht benutzen? für Variablen, nur Methodennamen.
? ist Konvention für methodnames, keine Variablen. Sie können keine Instanz Variable mit dem Namen @foo?
verwenden, jedoch könnten Sie eine Variable mit dem Namen @foo
verwenden und die (manuell erstellt) Getter-Methode foo?
nennen, wenn man will.
Monkey-Patching metaprogramming - vielleicht kann es eleganter gemacht werden, dass dies nur ein kurzer Entwurf ist, und ich habe nicht Metaprogrammierung für eine kleine Weile getan ...
# 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?
Mit diesem Ansatz können Sie DRY sein und das schöne Question bekommen. Sie müssen nur vielleicht einen besseren Namen als " bool_attr ", wie " bool_attr_accessor " oder etwas ähnliches.
holenDie Definitionen, die ich gemacht sind ein bisschen verschroben, in einem Sinne, dass die Fragezeichen in dem ursprünglichen Symbol vorhanden sind. Wahrscheinlich ein sauberer Ansatz wäre, die in question den Symbolnamen zu vermeiden und es bei der Definition des Verfahrens hängen -. Sollte weniger verwirrend sein
Oh, und fast vergessen die obligatorische Link zu enthalten: metaclasses deutlich sehen