我们经常使用&
符号在这样的符号上缩短块:
some_array.group_by(&:foo)
是否有类似的方法来缩短{|x| x}
等表达式?
some_array.group_by{|x| x}
如果方法Object#self
返回self
,那么我们可以
some_array.group_by(&:self)
但不幸的是,没有这样的方法。就字符数而言,可能会更长,但可读性会提高。
答案 0 :(得分:30)
是即可。 #itself
已在Ruby 2.2.0中实现。
您可以访问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
答案 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)
无论你喜欢什么地方。这可能会使您的保修失效。
答案 2 :(得分: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源代码中看到它。
如果您使用的是早于2.2.0的Ruby版本,则可以通过将此代码放在项目中的某个位置并确保它是必需的,轻松地将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