0

したがって、一般的なRubyデータ型の機能を拡張するという観点からのベストプラクティスについて質問があります。

したがって、Railsにはもちろんpluralize、文字列を取得して複数形にする優れた方法があります。私が特に興味を持っているのは、あなたが電話できることです

"square".pluralize

受け取ります

=> "squares"

その見返りに。私がやりたいのは、ハッシュを除いて、同様のことです。この質問のために、ハッシュのpluralize_eachそれぞれkeyとを複数形にするメソッドがあるとしましょう。value

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
class Hash
  def pluralize_each
    each { |key,value| puts "#{key.pluralize} => #{value.pluralize}" }
  end
end

インスタンスで独自のメソッドを呼び出したい場合はHash、クラスを再度開く以外の方法があるとは思えません。

于 2012-06-19T14:16:29.173 に答える
0

Rubyのオブジェクト指向パラダイムを考えると、ハッシュのサブメソッドを作成することは間違いなく最良の方法です。しかし、何らかの理由でグローバルメソッドを作成したい場合は、引数クラスをチェックする2つの方法があります。

1つは「instance_of?」です。(引数が特定のクラスのものであることをテストします)または「kind_of?」(これによりサブクラスが可能になります。一般的には良い考えです)。したがって、たとえば:

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

本当です。

したがって、この方法で引数を確認できます。もう1つのオプションは、オブジェクトがハッシュのように機能するかどうかを確認するための「ダックタイピング」です。たとえば、オブジェクトに「.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 に答える