Question

Apprendre Ruby. Je suis sous l'impression que doivent être nommés attributs booléens comme suit:

my_boolean_attribute?

Cependant, je reçois des erreurs de syntaxe lorsque vous essayez de faire ce qui suit:

class MyClass
  attr_accessor :my_boolean_attribute?

  def initialize
    :my_boolean_attribute? = false
  end
end

Apparemment, Ruby est haïssait le "?". Est-ce la convention? Qu'est-ce que je fais mal?

Était-ce utile?

La solution

Edit: trois ans plus tard; les temps, ils sont un Changin' ...

de réponse Julik est la plus simple et la meilleure façon d'aborder le problème ces jours-ci:

class Foo
  attr_accessor :dead
  alias_method :dead?, :dead # will pick up the reader method
end

Ma réponse à la question initiale suit, pour la postérité ...


La version courte:

Vous ne pouvez pas utiliser un point d'interrogation au nom d'une variable d'instance.

La version plus longue:

Prenons, par exemple, attr_accessor :foo - il est simplement conceptuellement un peu de sucre syntaxique pour ce qui suit:

def foo
  @foo
end

def foo=(newfoo)
  @foo = newfoo
end

En outre, le suffixe marque de question est la plupart du temps juste une convention pour indiquer que la valeur de retour d'une méthode est un booléen.

La meilleure approximation que je peux faire de ce que vous allez pour ici ...

class MyClass

  def initialize
    @awesome = true
  end

  def awesome?
    @awesome
  end

end

Dans ce cas, il peut y avoir un cas à effectuer pour l'utilisation attr_accessor - après tout, il peut être explicite que vous travaillez directement avec un attribut booléen. En général, je sauve le suffixe marque de question quand je suis en oeuvre un procédé dont la valeur retournée est booléenne en fonction des conditions un peu plus complexe que juste la valeur d'un attribut.

Vive!


Edition, deux ans plus tard, après un commentaire récent:

  1. Ruby applique certaines conventions de nommage. Symboles en Ruby ne peuvent pas avoir des points d'interrogation. Ainsi, les invocations de :my_boolean_attribute? les deux échouent avec un NameError Edit:. Incorrect, il suffit d'utiliser la syntaxe cité pour un symbole, par exemple, :"my_attribute?"
  2. Les symboles sont immuables, en essayant d'attribuer à un jetteront un SyntaxError.

Autres conseils

La meilleure façon d'ajouter rapidement une « méthode de question » est d'utiliser aliasing pour la méthode de lecture

class Foo
  attr_accessor :dead
  alias_method :dead?, :dead # will pick up the reader method
end 

Le symbole attr_accessor implique que le nom de la variable est @my_boolean_attribute, de sorte que ce que vous devriez installerez (pas le symbole).

En outre, vous ne pouvez pas utiliser? pour les variables, les noms que la méthode.

? est convention pour methodnames, pas les variables. Vous ne pouvez pas utiliser une variable d'instance nommée @foo?, mais vous pouvez utiliser une variable nommée @foo et nommez la méthode de lecture (créé manuellement) foo? si vous voulez.

Monkey-patcher métaprogrammation - c'est peut-être il peut être plus élégant, seul un projet rapide, et je n'ai pas fait Méta un peu de temps ...

 # 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?

Avec cette approche, vous pouvez être sec et obtenir la belle questionmark aussi. Vous pourriez avoir besoin de choisir un meilleur nom que " bool_attr ", comme " bool_attr_accessor " ou quelque chose de similaire.

Les définitions que j'ai fait sont un peu grincheux, dans un sens que le point d'interrogation est présent dans le symbole d'origine. Probablement une approche plus propre serait d'éviter le questionmark au nom du symbole et l'ajouter lors de la définition de la méthode -. Devrait être moins confus

Oh, et presque oublié d'inclure le lien obligatoire: Voir métaclasses clairement

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top