2013-06-05 105 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 
相关问题