0

所以我有一个关于扩展常见 Ruby 数据类型功能的最佳实践的问题。

因此,Rails 当然有一个很好的方法pluralize,它接受一个字符串并将其复数。我特别感兴趣的是你可以打电话

"square".pluralize

并收到

=> "squares"

作为回报。我想做的是类似的事情——除了哈希。为了这个问题,假设我有一个方法pluralize_each可以将每个keyvalue的散列复数。

def pluralize_each hash
  hash.each {|key,value| puts key.pluralize + "=>" + value.pluralize }
end

我怎样才能操纵这个方法,以便我可以只在一个哈希上调用它?例如,我希望能够调用

{"cat" => "dog"}.pluralize_each
#=> {"cats" => "dogs"}

(让我们忘记这个特殊的方法现在还不能完全发挥作用,有嵌套的哈希等。)

除了扩展 Hash 类之外,还有什么方法可以做到这一点?我想会有办法的。

4

3 回答 3

2

使用模块:

module HashPluralize
  def pluralize
    each { |key,value| puts "#{key.pluralize} => #{value.pluralize}" }
  end
end

Hash.send(:include, HashPluralize)

# Usage example:
{'user' => 'product'}.pluralize
users => products

编辑:为什么?

@KL-7 合法地要求类编辑与模块扩展。这是我的意见:

如果您正在编写一些有机的东西,模块对于优化重构/代码组织可能很有用。例子:

module Pluralization

  def self.included(klass)
    klass.send :include, Pluralization.const_get(klass.to_s)
  rescue TypeError
    raise NotImplementedError.new("A pluralization method for the #{klass}" +
            " class is not supported at the moment")
  end

  module Array
    def pluralize
      'array pluralization implementation'
    end
  end

  module Hash
    def pluralize
      'hash pluralization implementation'
    end
  end

end

Array.send :include, Pluralization
Hash.send :include, Pluralization

puts Array.new.pluralize
puts Hash.new.pluralize

该模块允许您定义一种干净的方式来定义各种类的复数形式;您可以添加配置,将复数方法分离到各个文件中,等等。

无论如何,如果您只是想向pluralizeHash 类添加一个方法,那么编辑 Hash 类没有问题(只要确保您没有覆盖另一个方法,并method_defined?检查 fe)

于 2012-06-19T14:18:41.947 回答
0

鉴于 Ruby 的面向对象范式,制作 Hash 的子方法绝对是最好的方法。但是如果你出于某种原因想要创建一个全局方法,那么有两种方法可以检查参数类。

一个是“instance_of?” (测试参数是否属于特定类)或“kind_of”?(允许子类;通常是个好主意)。例如:

{a: 1, b: 2, c: 3}.kind_of? Hash

是真的。

所以你可以用这种方式检查你的论点。另一个选项是“duck-typing”来查看对象是否像哈希一样,例如查看它是否具有“.keys”方法:

{a: 1, b: 2, c: 3}.respond_to? :keys

但是,我会坚持在 Hash 类中插入方法:

class Hash
  def ...
  end
end

或定义 Hash 的子类并将方法放在那里:

class Hash_with_plural < Hash
  def ...
  end
end

因为它更干净。

于 2012-06-19T18:23:08.217 回答
0
class Hash
  def pluralize_each
    each { |key,value| puts "#{key.pluralize} => #{value.pluralize}" }
  end
end

如果您想在实例上调用自己的方法,Hash我怀疑除了重新打开类之外还有其他方法。

于 2012-06-19T14:16:29.173 回答