最近我想出了这个方法:
module Enumerable
def transform
yield self
end
end
方法的目的与tap
方法类似,但具有修改对象的能力。
例如,使用此方法,我可以按链式更改数组中的顺序:
array.do_something.transform{ |a| [a[3],a[0],a[1],a[2]] }.do_something_else
而不是这样做:
a0,a1,a2,a3 = array.do_something
result = [a3, a0, a1, a2].do_something_else
使用此方法时还有其他便利,但......
该方法非常简单,所以我想某处应该是已经构建的具有相同目的的方法。
这种红宝石方法有类似的吗?
答案 0 :(得分:1)
我现在无法测试,但您应该能够做到这样的事情:
array= [1,2,3]
array.tap{ |a| a.clear }
Tap运行块然后返回self,如果你可以在块中修改self,它将传回更新的数组。在我的示例中,clear在块中修改self,以便返回修改后的self。
如果您需要此功能,我建议您添加do_something_else等方法!修改自我然后在你的点击块中运行它。
答案 1 :(得分:1)
您可以使用instance_eval
:
在接收器的上下文中评估(...)给定的块
示例:
%w(a b c d).instance_eval{|a| [a[3], a[0], a[1], a[2]] }
# => ["d", "a", "b", "c"]
或使用self
:
%w(a b c d).instance_eval{ [self[3], self[0], self[1], self[2]] }
# => ["d", "a", "b", "c"]
答案 2 :(得分:0)
那么问题在哪里?这一切都取决于你想进入功能编程领域的程度。只需阅读Learn You a Haskell for Great Good!
即可,您将永远不会相同。一旦你打开这个Pandora盒子就很难停下来,经过一些实验后我想知道我是否还在编写Ruby代码。比较(使用为transform
定义的Object
方法)
h = {}
{:a => :a_method, :b => :b_method}.each do |k, m|
h[k] = some_object.__send__(m)
end
h.some_other_method
和
some_object.transform(&THash[:a => :a_method, :b => :b_method]).some_other_method
其中
THash =
lambda do |t|
h = {}
kms = t.map { |k, v| [k, v.to_proc] }
lambda do |x|
kms.each { |k, m| h[k] = m[x] }
end
end
因此,如果您想要根据转换来考虑对象,那么它就非常有意义,并且确实使代码更具可读性,但它不仅仅是transform
方法,您还需要定义经常使用的泛型转换。
基本上它被称为point-free
编程,虽然有人称之为pointless
。取决于你的心态。