是否有一个简短的方法来写`{| x | X}`?

时间:2013-06-05 06:10:40

标签: ruby

我们经常使用&符号在这样的符号上缩短块:

some_array.group_by(&:foo)

是否有类似的方法来缩短{|x| x}等表达式?

some_array.group_by{|x| x}

如果方法Object#self返回self,那么我们可以

some_array.group_by(&:self)

但不幸的是,没有这样的方法。就字符数而言,可能会更长,但可读性会提高。

3 个答案:

答案 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