Combinatory method like tap, but able to return a different value?

风流意气都作罢 提交于 2019-11-29 23:55:42

Define Object#as:

class Object
  def as
    yield self
  end
end

And now you can write:

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
def best_nice_method
  something_complex(a, b, c).tap |obj|
    break obj.one_more_method_call if a_predicate_check?
  end
end

The magic is break in tap returns another value.

new

ruby 2.5 has yield_self which exactly you want. https://stackoverflow.com/a/47890832/683157

I found a method in the Facets gem that might be what you were looking for: Kernel#ergo

So your original method:

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

might end up looking something like this:

require 'facets/kernel/ergo'

def nice_method
  something_complex(a, b, c).ergo do |_| 
    a_predicate_check? ? _.one_more_method_call : _
  end
end

I needed to do something like this and I like tokland's answer, but I didn't want to pollute Object for the small script I was writing. Instead, I made use of tap on an array:

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

instance_eval can be misused for this purpose

"this".instance_eval { |test| test + " works" }

since 2.5 it is possible to use yield_self

"easy".yield_self{ |a| a + " peasy" }

Read more:

https://ruby-doc.org/core-1.9.3/BasicObject.html#method-i-instance_eval

https://ruby-doc.org/core-2.5.0/Object.html#method-i-yield_self

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!