2010-07-23 17 views
7

seguente frammento di codice da rotaieQual è l'operatore <= su Ruby Classes?

def rescue_from(*klasses, &block) 
    options = klasses.extract_options! 

    unless options.has_key?(:with) 
     if block_given? 
     options[:with] = block 
     else 
     raise ArgumentError, "Need a handler. Supply an options hash that has a :with key as the last argument." 
     end 
    end 

    klasses.each do |klass| 
     key = if klass.is_a?(Class) && klass <= Exception 
     klass.name 
     elsif klass.is_a?(String) 
     klass 
     else 
     raise ArgumentError, "#{klass} is neither an Exception nor a String" 
     end 

     # put the new handler at the end because the list is read in reverse 
     self.rescue_handlers += [[key, options[:with]]] 
    end 
    end 
end 

Avviso all'operatore < =

che cos'è?

risposta

9

Vedi http://ruby-doc.org/core/classes/Module.html#M001669 per la documentazione su tutti gli operatori di confronto esposti da moduli (e quindi classi).

In questo caso specifico: "Restituisce vero se mod è una sottoclasse dell'altro o è uguale all'altro. Restituisce nil se non c'è alcuna relazione tra i due. (Pensare alla relazione in termini di definizione della classe : "classe A < B" indica "A < B"). "

1

Abbastanza sicuro che significa klass è un tipo di eccezione.

In genere però significa "minore o uguale a". Quindi quel codice potrebbe dire se è almeno una classe ma non un'eccezione ... fare qualcosa. Ma allora l'architettura di "meno di" sarebbe fuori luogo.

Dalla documentazione del codice

# gestori sono ereditate. Vengono cercati da destra a sinistra, da
# dal basso verso l'alto e in alto nella gerarchia. Il gestore della prima classe per
# che eccezione.is_a? (Klass) è vera è quella invocata, se presente.

3

è l'operatore per "LHS è la stessa classe o sottoclasse di RHS". < è l'operatore per "LHS è una sottoclasse di RHS."

Questo è sovraccarico stravagante degli operatori, ma è da notare che le dichiarazioni di sottoclasse in Ruby anche usare <, come in

class SomeClass < ActiveRecord::Base 

così almeno è coerente in questo senso.

(LHS: sinistra, RHS: lato destro)

+0

Perché pensi che sia "stravagante sovraccarico di operatori"? La relazione di ereditarietà impone un ordinamento parziale sulle classi e, in generale, il simbolo utilizzato per rappresentare le relazioni che impongono ordinamenti parziali è '<=' (o piuttosto '≤' ma mentre questo è un nome di metodo valido in Ruby, non è valido nome dell'operatore). Sei corretto nella misura in cui il solito operatore per denotare una relazione di sottotipo è '<:', ma non è né un metodo valido né un nome operatore in Ruby, quindi personalmente ritengo che '<=' sia abbastanza buono. Sicuramente batte il comune abuso dell'uso di '+' per set union (che dovrebbe essere '∪'). –

4

È paragonabile al metodo is_a? che restituisce true se la classe ricevitore è una sottoclasse dell'argomento; Consideriamo:

Fixnum.superclass # => Integer 
Fixnum <= Integer # => true