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?

War es hilfreich?

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:

  1. erzwingt Rubin bestimmte Namenskonventionen. Symbole in Ruby kann keine Fragezeichen haben. So Anrufungen von :my_boolean_attribute? beide werden mit einem NameError scheitern Edit:. Nicht richtig, nur die zitierte Syntax für ein Symbol verwenden, zum Beispiel :"my_attribute?"
  2. 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.

holen

Die 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

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top