将方法添加到模块内的标准类

时间:2013-03-29 11:48:19

标签: ruby module

例如,我想向类String添加新方法。但我不想让这种变化变得全球化(保持课堂干净是好的,是吗?)。

所以,而不是这段代码

class String
  def is_palindrome?
    self == self.reverse
  end
end

module MyModule
  class MyClass
    def filter_palindrome(str_arr)
      str_arr.select { |s| s.is_palindrome? }
    end
  end
end

我希望有这样的东西:

module MyModule
  class String
    def is_palindrome?
      self == self.reverse
    end
  end

  class MyClass
    def self.filter_palindrome(str_arr)
      str_arr.select { |s| s.is_palindrome? }
    end
  end
end

但是,当然,它不起作用(undefined method 'is_palindrome?' for :String)。那么,我想要的是什么意思?如果有,实现它的最佳方法是什么?

1 个答案:

答案 0 :(得分:1)

如果您使用的是Ruby 2.0,则可以尝试refinements

module MyModule
  module StringAlter
    refine String do
      def is_palindrome?
        self == self.reverse
      end
    end
  end
end

using MyModule::StringAlter
module MyModule
  class MyClass
    def self.filter_palindrome(str_arr)
      str_arr.select { |s| s.is_palindrome? }
    end
  end
end

如果在Ruby 2.0之前,您无法直接实现此目的。对String的更改将是全局的。但是,为什么不编写辅助方法并将其称为s.is_palindrome?,而不是is_palindrome?(s)。然后,您不必重新打开String,并且可以限制is_palindrome?仅在某个给定范围内可用。

这是Python的方式(self),以及C#扩展方法。