Qual è il modo corretto di farlo in Ruby?Idiota rubino: chiamata metodo o altro default
def callOrElse(obj, method, default)
if obj.respond_to?(method)
obj.__send__(method)
else
default
end
end
Qual è il modo corretto di farlo in Ruby?Idiota rubino: chiamata metodo o altro default
def callOrElse(obj, method, default)
if obj.respond_to?(method)
obj.__send__(method)
else
default
end
end
Perché non è stato offerto come una risposta:
result = obj.method rescue default
Come con @slhck, probabilmente non userei questo quando sapevo che c'era una ragionevole possibilità che obj non risponda al metodo, ma è un'opzione.
Semplice com'è, questo ha l'inconveniente maggiore di oscurare qualsiasi eccezione sollevata da obj.method, non si saprà se non ha avuto alcun metodo o ha semplicemente fallito. Personalmente eviterei di salvare il posto quando è possibile. – tokland
-1 Per la ragione che @tokland ha menzionato. Non puoi davvero usarlo come strategia generale. – Jazzepi
probabilmente sarei andare per
obj.respond_to?(method) ? obj.__send__(method) : default
Questo è molto più pulito, ma è essenzialmente la stessa funzionalità. Pensavo che ci sarebbe stato un modo migliore per farlo. – dsg
Beh, cosa vuoi se non lo stesso _funzionalità_? :) Per quanto mi riguarda, non c'è modo di aggirare questa decisione. Ma forse qualcuno ha un'idea. – slhck
Speravo in qualcosa di simile: 'x = obj.method || default'. – dsg
Così si vuole qualcosa di simile a x = obj.method || default
? Ruby è un linguaggio ideale per costruire le proprie costruzioni bottom-up:
class Object
def try_method(name, *args, &block)
self.respond_to?(name) ? self.send(name, *args, &block) : nil
end
end
p "Hello".try_method(:downcase) || "default" # "hello"
p "hello".try_method(:not_existing) || "default" # "default"
Forse non ti piace questa chiamata indiretta con i simboli? nessun problema, poi guardare Ick s' maybe
stile e utilizzare un oggetto proxy (si può capire l'attuazione): nota
p "hello".maybe_has_method.not_existing || "default" # "default"
Side: Non sono un esperto OOP, ma è la mia comprensione che si deve sapere se l'oggetto che stai chiamando ha in effetti un tale metodo in anticipo. O è nil
l'oggetto a cui si desidera controllare di non inviare metodi? Im questo caso Ick è già una bella soluzione: object_or_nil.maybe.method || default
Questa è generalmente una buona risposta, ma si noti che l'implementazione risulterà in qualsiasi metodo esistente che restituisca 'false' o 'nil' avendo invece usato il" default ". – Phrogz
@Phrogz: questo è un buon punto, ma in questo caso è improbabile che sia necessario un valore predefinito, basta scrivere la condizione "se obj.maybe.enabled?". Ad ogni modo, puoi sempre modificare il modello forse in base alle tue esigenze: "obj.maybe (: default => true) .active?", Ma "|| default" dovrebbe coprire i casi tipici. – tokland
EAFP (ad esempio, prova-eccetto qui) non è abbracciato nella comunità Ruby così com'è da Pythonistas? –
@ Karl. Non sto parlando per tutti i Rubyist, ma dover scrivere (almeno) quattro righe per qualcosa che potresti fare in uno è decisamente fastidioso per molti programmatori di Ruby (qualcosa che probabilmente non gli dispiacerebbe in Python, però). – tokland
Inoltre, non vorrei usare un try/except qui se ciò che l'OP intende include un comportamento __default__. Secondo me, se possono verificarsi entrambi i modi (ad esempio "send" e "default"), perché renderlo un "Eccezione"? – slhck