2013-07-18 15 views
9

Recentemente ho scoperto che è possibile rilevare se una classe/modulo include un'altra classe/modulo. Per esempio Array è Enumerable modo da poter fareFoo <Bar in Ruby

Array < Enumerable # true 

String, tuttavia, non è enumerabile

String < Enumerable #nil 

Che cosa esattamente sta succedendo qui? Come funziona questa sintassi in ruby?

risposta

8

Ecco come ottenere la catena antenato di una classe:

>> Array.ancestors 
=> [Array, Enumerable, Object, Kernel, BasicObject] 

Il metodo < restituisce vero se una classe è "sinistra" di un'altra classe nella catena degli antenati e false altrimenti:

>> Array < Object 
=> true 
>> Array < Enumerable 
=> true 

Il metodo < restituisce false se una classe non è "sinistra" o un'altra classe nella catena di antenati.

>> Enumerable < Array 
=> false 
>> Array < Array 
=> false 

Enumerable è un modulo che viene miscelato nella alla classe Array, ma non miscelato alla classe String.

>> Array.ancestors 
=> [Array, Enumerable, Object, Kernel, BasicObject] 
>> String.ancestors 
=> [String, Comparable, Object, Kernel, BasicObject] 

Se si include il modello Enumerable nella classe String, restituisce vero pure.

class String 
    include Enumerable 
end 

# Enumerable is now included in String 
String < Enumerable #true 

La sintassi funziona a causa di zucchero sintattico.Tutto è un oggetto in Ruby e zucchero sintattico viene anche utilizzato in operazioni di base come aggiunta:

>> 3 + 4 
=> 7 
>> 3.+(4) 
=> 7 

La sintassi esplicita per il metodo < è il seguente:

>> Array.<(Object) 
=> true 
>> Array.send(:<, Object) 
=> true 
4

Che cosa sta succedendo esattamente qui? Come funziona questa sintassi in ruby?

I String e Array classi ereditano dalla classe Class che eredita dalla classe Module che defines il metodo < classe come:

Restituisce vero se il modulo è una sottoclasse dell'argomento passato. Restituisce zero se non c'è alcuna relazione tra i due.

La sintassi:

Array < Enumerable 
String < Enumerable 

può essere visto come:

Array.< Enumerable 
String.< Enumerable 
+1

Il [ '<=>' metodo di istanza] (http://www.rubydoc.info/stdlib/core/Module#%3C%3D%3E-instance_method) di ['Class'] (http://www.rubydoc.info/stdlib/core/Class) è irrilevante qui. Il ['<' instance method] (http://www.rubydoc.info/stdlib/core/Module#%3C-instance_method) ha una sua definizione che non si basa su '<=>', come puoi vedere facendo clic su " Visualizza sorgente "nei documenti. –

+0

@ RoryO'Kane, grazie. Modificato. – Shoe

3

Se i due moduli appaiono in una catena antenato, allora l'ordinario <=> applica rispetto alla loro posizione in tale catena. In caso contrario, viene restituito nil.

Problemi correlati