这种红宝石方法有类似的吗?

时间:2012-06-28 13:58:32

标签: ruby enumerable

最近我想出了这个方法:

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

使用此方法时还有其他便利,但......

该方法非常简单,所以我想某处应该是已经构建的具有相同目的的方法。

这种红宝石方法有类似的吗?

3 个答案:

答案 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。取决于你的心态。