【问题标题】:Define a method that works on arrays of a specific type of object定义一个适用于特定类型对象数组的方法
【发布时间】:2011-03-23 12:28:40
【问题描述】:

在 C# 中,您可以编写这样的扩展方法:

public static Debt[] Foo(this Debt[] arr, int num)
{
    // Do something
}

这将允许您在一系列债务上使用Foo()debts.Foo(3)

你能在 Ruby 中做到这一点吗?我知道你可以编写一个适用于数组的方法:

class Array
  def foo
    # blah
  end
end

但这适用于所有类型的数组,而不仅仅是Debts的数组

提前致谢。

【问题讨论】:

    标签: ruby extension-methods


    【解决方案1】:

    extend 方法将实例方法添加到特定对象。所以在你的情况下它会是:

    class YourClass
      def foo
        # blah
      end
    end
    
    debts.extend(YourClass)
    debts.foo # now foo method is instance method of debts object
    

    实际上它为debts 对象创建了单例类,然后将方法添加到其中。但是你不能使用这个类,所以它叫“ghost”类

    【讨论】:

    • 感谢您的快速回答,但在我的程序中我应该在哪里调用debts.extend?我正在使用导轨。
    • 你的意思是有专门的地方像帮手吗?我不知道,但是在 Rails 中扩展通常用于安静混合 def self.included(base) base.extend ClassMethods end 是元编程,看看这个pragprog.com/screencasts/v-dtrubyom/…
    【解决方案2】:

    这会有点棘手,因为 Ruby 数组不是同构的。也就是说,您可以在数组中存储不同类型的对象。这将引导我找到一个解决方案,我需要首先验证数组中的所有对象都是Debt 类型,如果是,那么我可以使用foo 对数组进行操作。

    您可以继续打开Array 并添加foo 方法,但也许您应该创建一个FooArray 并扩展Array。这样你可以重新定义一些方法,例如<<push,以确保你只取Debts。既然您知道只有Debts 可以添加到您的数组中,您可以放心地调用foo()

    【讨论】:

      【解决方案3】:

      我相信您可以通过扩展 Ruby 的 Array 类或更好地定义自己的类 Array 类并将选定的数组方法委托给本机对象来做到这一点。

      Stack = Array.extract([
        :last,
        :push,
        :pop,
        :size,
        :clear,
        :inspect,
        :to_s
      ])
      

      为什么这比替代方法更好是explained here

      【讨论】: