2012-06-28 20 views
1

最近,我想出了這個方法:這種紅寶石方法有類似嗎?

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.9開始提供。 – texasbruce

+0

我的版本返回yield self的結果,即塊的結果不僅僅是我自己。 – megas

+0

更正:屈服於自我,這是你的方法。你沒有提到你也想回歸自我,並且有理由返回這個塊。 – texasbruce

回答

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"] 
+0

是的,它非常接近我的版本,但是你的版本更慢,然後我的2.2倍。 – megas

1

我現在不能測試這一點,但你應該能夠做這樣的事情:

array= [1,2,3] 
array.tap{ |a| a.clear } 

點擊運行,那麼該塊返回自我,所以如果你可以修改塊的自我,它會回傳更新的數組。在我的例子中,清除修改塊中的自我,以便修改後的自我被返回。

如果你想要這個功能,我會建議添加一個像do_something_else這樣的方法!修改自我,然後在你的水龍頭塊內運行它。

+0

對於這種事情,你可以用'instance_eval'替換'tap'並使用'self',這允許你返回一個副本而不必改變原來的變量 – tlehman

0

那麼問題在哪裏?這完全取決於你想進入函數式編程領域多遠。剛剛閱讀Learn You a Haskell for Great Good!,你永遠不會是一樣的。一旦你打開這個潘多拉盒子,真的很難停下來,經過一番試驗,我不知道我是否還在編寫Ruby代碼。比較(使用Object定義您的transform法)

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。取決於你的心態。

+0

問題在標題中,但我更新了問題。我已經嘗試了幾次Haskell,但是我沒有得到它,我希望我會一次,謝謝你的回答。 – megas