在 ruby 中评估 args 的简写方法

Short hand way to evaluate args in ruby

我目前在 ruby 程序中使用以下代码来评估传递给方法的可变长度参数。该程序是 运行 但是我想知道是否有一种简写的方法来编写它。 应该在我的原始描述中更具体,尝试重写数组的 Inject 方法 class(因此是机智的名字...)

因此,它需要能够接受最多两个 args,如果给定一个块,则最少为 0。

最难 case/s 处理的是第一个和第一个参数可以是 Fixnum 或 Symbol 的地方。如前所述,代码有效,只是在寻找整理它的方法。

class Array

  def enjict(*args)

    if args.length == 2 && args[0].is_a?(Fixnum) && args[1].is_a?(Symbol)
      start, symbol = args
    elsif args.length == 1
      raise ArgumentError unless args.first.is_a?(Symbol) || args.first.is_a?(Fixnum)
      symbol = args.first if args.first.is_a?(Symbol)
      start = args.first if args.first.is_a?(Fixnum)
    else
      raise ArgumentError unless block_given?
    end

    copiedArray = dup

    start = copiedArray.shift unless start

    if block_given?
      copiedArray.each { |num| start = yield(start, num) }
    else
      copiedArray.each { |num| start = start.send(symbol, num) }
    end
    start
  end
end

根据条件判断,如何将您的方法参数重构为:

def enjict(start, symbol, *options, &block)
  e = proc{ raise ArgumentError if options.length > 0 && !block_given? }
  e.call

  if start.is_a?(Fixnum) && symbol.is_a?(Symbol)
    # do something you want
  else
    e.call
  end
end

可悲的事实是:它很乱,而且您无能为力。几乎所有 Ruby 实现都在 Enumerable#inject 中实现了对解释器内部结构的特权访问,包括对参数的自省。 MRI、YARV、MRuby用C实现,MacRuby和RubyMotion在Objective-C、XRuby和JRuby在Java、Ruby.NET 和 C# 中的 IronRuby、RPython 中的 Topaz、PIR 中的 Cardinal 等等。

这是 Ruby 代码所不具备的。

Rubinius implements it in Ruby.

您可以通过(滥用)使用以下事实来使用类似的技巧:可选参数的默认参数表达式可以是 any 任意复杂的 Ruby 表达式并且这些表达式的局部变量成为方法的局部变量。这是确定是否传递参数的常用技巧:

def inject(initial=(no_initial = true; nil), sym=(no_sym = true; nil))
  sym, initial = initial, nil if !block_given && no_sym
  # and so on …
end