我正在经历一个阶段,试图避免临时变量和过度使用条件,我可以使用更流畅的编码风格。我非常喜欢在需要返回值的地方使用#tap
,但是在返回之前要对它做一些处理。
def fluid_method
something_complicated(a, b, c).tap do |obj|
obj.update(:x => y)
end
end
字符串
Vs.程序:
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
型
显然上面的例子很简单,但这是ruby社区中非常常见的编码风格。我有时也会使用#inject
来让一个对象通过一系列过滤器:
things.inject(whatever) do |obj, thing|
thing.filter(obj)
end
型
Vs.程序:
obj = whatever
things.each do |thing|
obj = thing.filter(obj)
end
obj
型
现在我面临着反复使用以下条件,并寻找一种更流畅的方法来处理它:
def not_nice_method
obj = something_complex(a, b, c)
if a_predicate_check?
obj.one_more_method_call
else
obj
end
end
型
(稍微)干净的解决方案是以重复为代价避免临时变量:
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
型
我忍不住想在这里使用类似#tap
的东西。
我在这里还可以遵循哪些模式。我意识到这对一些人来说只是无意义的糖,我应该转移到更有趣的问题上,但我正在努力学习以更实用的风格写作,所以我只是好奇长期的rubyists已经确定了什么是解决这种情况的好方法。这些例子被大大简化了。
6条答案
按热度按时间hujrc8aj1#
定义
Object#as
:字符串
现在你可以写:
型
kyks70gy2#
字符串
神奇的是
break
在tap
中返回另一个值。新
Ruby 2.5有
yield_self
,这正是你想要的。https://stackoverflow.com/a/47890832/68315713z8s7eq3#
instance_eval
可能会被滥用于此目的"this".instance_eval { |test| test + " works" }
个由于2.5,可以使用
yield_self
"easy".yield_self{ |a| a + " peasy" }
个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
wwodge7n4#
我在Facets gem中发现了一个方法,它可能是你正在寻找的:内核#ergo
所以你原来的方法是:
字符串
可能最终看起来像这样:
型
t1qtbnec5#
我需要做这样的事情,我喜欢tokland的答案,但我不想因为我写的小脚本而污染Object。相反,我在数组上使用了
tap
:字符串
gdrx4gfi6#
字符串
典型用法:
型
您的案例:
型
甚至
型