videos variacion probabilidad permutaciones permutacion entre ejercicios distinguir diferencia conteo como combinatoria combinaciones combinacion ruby theory combinators

ruby - variacion - ¿Método combinatorio como tap, pero capaz de devolver un valor diferente?



probabilidad combinatoria formula (5)

Defina el Object#as :

class Object def as yield self end end

Y ahora puedes escribir:

def not_sure_this_is_nice_enough_method1 something_complex(a, b, c).as do |obj| a_predicate_check? ? obj.one_more_method_call : obj end end

Estoy pasando por una fase de tratar de evitar las variables temporales y el uso excesivo de condicionales, donde puedo usar un estilo de codificación más fluido. Me ha gustado mucho usar #tap en lugares donde quiero obtener el valor que necesito para devolver, pero haz algo con él antes de devolverlo.

def fluid_method something_complicated(a, b, c).tap do |obj| obj.update(:x => y) end end

Vs. el procedimental:

def non_fluid_method obj = something_complicated(a, b, c) obj.update(:x => y) obj # <= I don''t like this, if it''s avoidable end

Obviamente, los ejemplos anteriores son simples, pero este es un estilo de codificación bastante común en la comunidad ruby, no obstante. A veces #inject para pasar un objeto a través de una serie de filtros también:

things.inject(whatever) do |obj, thing| thing.filter(obj) end

Vs. el procedimental:

obj = whatever things.each do |thing| obj = thing.filter(obj) end obj

Ahora enfrento el uso repetido de una condición como la siguiente, y busco un enfoque más fluido para manejarlo:

def not_nice_method obj = something_complex(a, b, c) if a_predicate_check? obj.one_more_method_call else obj end end

La solución (ligeramente) más limpia es evitar la variable temporal a costa de la duplicación:

def not_nice_method if a_predicate_check? something_complex(a, b, c).one_more_method_call else something_complex(a, b, c) end end

Sin embargo, no puedo evitar sentir el deseo de usar algo como #tap aquí.

¿Qué otros patrones podría seguir aquí? Me doy cuenta de que esto no es más que una simple falta de sentido para algunas personas y que simplemente debería pasar a problemas más interesantes, pero estoy tratando de aprender a escribir en un estilo más funcional, así que tengo curiosidad por lo que los rubyistas a largo plazo han determinado. Ser buenas maneras de enfrentar situaciones como esta. Estos ejemplos son enormemente simplificados.


Encontré un método en la gema de Facetas que podría ser lo que estabas buscando: Kernel#ergo

Así que tu método original:

def not_nice_method obj = something_complex(a, b, c) if a_predicate_check? obj.one_more_method_call else obj end end

podría terminar buscando algo como esto:

require ''facets/kernel/ergo'' def nice_method something_complex(a, b, c).ergo do |_| a_predicate_check? ? _.one_more_method_call : _ end end


Necesitaba hacer algo como esto y me gusta la respuesta de tokland, pero no quería contaminar a Object por el pequeño script que estaba escribiendo. En su lugar, hice uso de tap en una matriz:

[something_complicated].tap { |s| s[0] = new_cool_thing)}.first



def best_nice_method something_complex(a, b, c).tap |obj| break obj.one_more_method_call if a_predicate_check? end end

La magia es break in tap devuelve otro valor.

nuevo

Ruby 2.5 se ha yield_self que exactamente quieres. https://.com/a/47890832/683157