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?

È stato utile?

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:

  1. Rubino fa rispettare certe convenzioni di denominazione. Simboli in Ruby non possono avere punti di domanda. Così invocazioni di :my_boolean_attribute? sia non riuscirà con un NameError Edit:. Non è corretta, basta usare la sintassi citato per un simbolo, per esempio, :"my_attribute?"
  2. 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

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top