2013-06-05 28 views
25

我們經常使用在這樣一個象徵符號&縮短塊:是否有簡寫的方法來編寫`{| x | X}`?

some_array.group_by(&:foo) 

有沒有類似的方式來縮短像{|x| x}表情?

some_array.group_by{|x| x} 

如果有一個方法Object#self返回self,那麼我們可以做

some_array.group_by(&:self) 

但不幸的是,有沒有這樣的方法。就字符數而言,它可能會更長,但可讀性會提高。

+1

沒有'it'作爲常規,恐怕 – Ven

+3

這是[識別功能](HTTP://en.wikipedia .ORG /維基/ Identity_function)。 'IDENT = Proc.new {| x | X}; array.group_by(IDENT)'。 – user2246674

+0

在這種情況下'to_proc'是否有意義?我可能是錯的。 – squiguy

回答

29

。在Ruby 2.2.0中實現了#itself


您可以訪問關於此功能的Ruby核心團隊討論here

作爲一個有趣的模擬,#ergo方法has been proposed,這將產生接收器給定的塊。

如果您還沒有升級到Ruby 2.2.0,你不妨反向移植#itself和/或定義#ergo如下:

class Object 
    def itself; self end 
    def ergo 
    fail ArgumentError, "Block expected!" unless block_given? 
    yield self 
    end 
end 

然後:

some_array.group_by &:itself 
+0

聽到這個消息的好消息。感謝您的信息。希望它很快就會實施。 – sawa

+0

嗯,他們把它分配到「下一個小版本」,但他們已經在2.1上工作了,這個功能仍然被阻止。所以,也許「下一個未成年人」並不意味着「立即接下來」:-)))我猜他們非常忙碌,仍然能夠迴應建議。 –

+0

太棒了! :)'+ 1'給你。 –

17

那麼,有沒有內置的,據我知道,但你可以做一個可重複使用的身份塊:

id = Proc.new {|x| x} 
some_array.group_by(&id) 

然後,如果真的希望這是一個語言特性:

class Object 
    def it 
    Proc.new {|x| x} 
    end 
end 

然後你就可以做

some_array.group_by(&it) 

你喜歡的地方。這可能會使您的保修失效。

+0

這實際上就是我在評論中所談論的。 +1 – squiguy

12

是的!在Ruby 2.2.0中添加了方法Kernel#itself。此方法僅返回它被稱爲上的對象,所以你可以寫:

some_array.group_by(&:itself) 

你可以看到這個功能,這裏的廣泛討論:https://bugs.ruby-lang.org/issues/6373。 RafaelFrança在消息#53中提交了該補丁。您可以通過查看object.c來查看官方Ruby源代碼。

如果您使用的是Ruby的版本早於2.2.0的,你可以很容易地把這個代碼在某處你的項目,並確保它被需要時添加Kernel#itself到您的項目:

module Kernel 
    def itself 
    self 
    end 
end if !Kernel.instance_methods.include?(:itself) 

然而,猴子補丁的Ruby核心的一部分,這可能是危險的,我不會推薦它,如果你正在做可重用的代碼,就像一個寶石。相反,我會建議只是讓自己身份的功能,通過user2246674的建議:

module MyLibrary 
    IDENT = Proc.new { |x| x } 

    array.group_by(&IDENT) 
end 
相關問題