¿Cuál es la forma correcta de hacer esto en Ruby?Ruby modismo: método de llamada o por defecto
def callOrElse(obj, method, default)
if obj.respond_to?(method)
obj.__send__(method)
else
default
end
end
¿Cuál es la forma correcta de hacer esto en Ruby?Ruby modismo: método de llamada o por defecto
def callOrElse(obj, method, default)
if obj.respond_to?(method)
obj.__send__(method)
else
default
end
end
Debido a que no se ha ofrecido como una respuesta:
result = obj.method rescue default
Al igual que con @slhck, probablemente no usaría esto cuando sabía que no había una posibilidad razonable de que obj no responda al método, pero es una opción.
Simple como es, esto tiene el principal inconveniente de sombrear cualquier excepción que obj.method plantea, no sabrá si no tenía ningún método o simplemente falló. Yo personalmente evitaría rescates en el lugar siempre que sea posible. – tokland
-1 Por la razón que @tokland mencionó. Realmente no puedes usar esto como una estrategia general. – Jazzepi
probablemente iría para
obj.respond_to?(method) ? obj.__send__(method) : default
Esto es mucho más limpio, pero es esencialmente la misma funcionalidad. Pensé que habría una mejor manera de hacer esto. – dsg
Bueno, ¿qué quieres si no es la misma _funcionalidad_? :) En lo que a mí respecta, no hay forma de eludir esta decisión. Pero tal vez alguien tenga una idea. – slhck
Esperaba algo como: 'x = obj.method || predeterminado'. – dsg
Así que quieres algo similar a x = obj.method || default
? Ruby es un lenguaje ideal para construir sus propias construcciones de abajo hacia arriba:
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"
Tal vez no te gusta esta llamada indirecta con símbolos? no hay problema, y luego mirar Ick 's maybe
estilo y utilizar un objeto proxy (se puede averiguar la implementación): Nota
p "hello".maybe_has_method.not_existing || "default" # "default"
lateral: No soy experto programación orientada a objetos, pero tengo entendido que usted debe saber si el objeto que está llamando tiene efectivamente dicho método de antemano. ¿O es nil
el objeto que desea controlar para no enviar métodos? Im este caso Ick ya es una buena solución: object_or_nil.maybe.method || default
Generalmente, esta es una buena respuesta, pero tenga en cuenta que la implementación dará como resultado cualquier método existente que devuelva 'false' o' nil' teniendo el valor "predeterminado" en su lugar. – Phrogz
@Phrogz: ese es un buen punto, pero es poco probable que necesite un valor predeterminado en este caso, simplemente escriba la condición "if obj.maybe.enabled?". De todos modos, siempre puede modificar el patrón tal vez según sus necesidades: "obj.maybe (: default => true) .active?", Pero "|| default" debe cubrir los casos típicos. – tokland
¿EAEP (es decir, usar try -excepto aquí) no está incluido en la comunidad Ruby como lo hace Pythonistas? –
@Karl. No estoy hablando para nada de Rubyist, pero tener que escribir (al menos) cuatro líneas para algo que podrías hacer en uno es definitivamente molesto para muchos programadores de Ruby (algo que probablemente no les importaría en Python, sin embargo). – tokland
Además, no utilizaría un constructo try/except aquí si lo que el OP pretende incluye un comportamiento __default__. En mi opinión, si se pueden producir ambas formas (es decir, 'enviar' y' predeterminado'), ¿por qué convertirlo en una "Excepción"? – slhck