5

Railsで整数クラスにメソッドを追加するのに最適な場所はどこですか? to_metersおよびto_milesメソッドを追加したいと思います。

4

7 に答える 7

11

Numeric (または整数など) クラスをいじって単位変換を取得することに心を向けている場合は、少なくとも論理的に、実際の値を使用して実行してください。

最初に、単位の種類 (メートル、フィート、キュビットなど) と作成時の値を格納する Unit クラスを作成します。次に、ユニットが持つことができる有効な値に対応する一連のメソッドを Numeric に追加します。これらのメソッドは、メソッド名として記録された型を持つ Unit オブジェクトを返します。Unit クラスは、対応する単位値を持つ別の単位タイプに変換する一連の to_* メソッドをサポートします。そうすれば、次のコマンドを実行できます。

>> x = 47.feet.to_meters
=> 14.3256
>> x.inspect
=> #<Unit 0xb795efb8 @value=14.3256, @type=:meter>

それを処理する最善の方法は、おそらく Unit クラスの変換型と式のマトリックスであり、次に method_missing を使用して、特定の型を別の型に変換できるかどうかを確認します。数値クラスでは、method_missing を使用して、指定されたメソッドをユニット型としてサポートしているかどうかを Unit に問い合わせます。サポートしている場合は、数値を値として使用して、要求された型のユニット オブジェクトを返します。次に、変換行列を拡張する unit に register_type および register_conversion クラス メソッドを追加することで、実行時に単位と変換を追加することをサポートできます。Numeric は「自動的に」機能を取得します。

どこに置くかについては、lib/units.rb ファイルを作成します。このファイルには、Numeric への monkey_patch も含まれます。次に、lib/units.rb ファイルを必要とする config/environment.rb bu で初期化します。

于 2008-11-07T09:32:18.443 に答える
2

通常(そして論理的に)、整数はマイルやメートルに変換できません。整数で初期化され、size_in_milesやsize_in_metersなどのメソッドを含む「Feet」や「inches」などの新しいクラスを作成したい場合があるようです。便宜上、これらのメソッドは10進数またはfloat型を返すことができますが、milesクラスまたはmetersクラスを作成することもできます。

別のメソッドとして、次のようなシグネチャを持つ静的メソッドを新しいクラスに作成することをお勧めします。

Float feetToMiles(integer I)

あなたが呼ぶだろう

miles = Feet.feetToMiles(5280);

取得しますmiles = 1.0

于 2008-11-05T21:47:13.923 に答える
2

このタスクを実行するために必要なときにスコープに含める独自のモジュール/ライブラリを作成します。

「requre'unitCoversions'」など

そして、たぶん、あなたが十分に一生懸命に見れば、誰かがすでにこれをしているでしょう:)

ただし、ネイティブコアクラスを変更しようとしないでください。これはMiseryでのみ終了します。

(また、拡張したいクラスは'numeric'であり、整数と浮動小数点数の両方に適用されます:))

なぜ私がこれをすべきでないのか完全には明らかではありません...Railsはこれを文字列クラスに対して行い、大成功を収めています。

それができるからといって、それがなされるべきだという意味ではありません。知られている「モンキーパッチ」は、あらゆる種類の奇妙な副作用をもたらす可能性があり、間違って行われると壮大な失敗になる可能性があります。

良い選択肢がないときにそれを行います。

本当に何かやりたいことがあれば、コアクラスにモンキーパッチを当てるだけでフレームワーク全体を構築できるからです。

たとえば、データベースをその頭で反転させます。

5.getArtist(); 
10.getEvent(); 
100.getTrack(); 

などなど。それを行うための悪い方法の数に制限はありません。

"Bob".createUser(); 

カップの惨めさ。

実用的なことをしたい場合は、Convertクラスまたは関数を用意してください。

convert( 3 , { :from=>:miles, :to=>:meters }); 

少なくとも、グローバル名前空間とコア関数をそのように汚染しているわけではなく、より一貫性のある意味があります。

于 2008-11-05T21:48:47.490 に答える
2

なぜだけではないのですか?

class Feet
  def self.in_miles(feet)
    feet/5280
  end
end

利用方法:

Feet.in_miles 2313

または多分それを別の方法で見てください:

class Miles
  def self.from_feet(feet)
    feet/5280
  end
end

Miles.from_feet 2313
于 2008-11-06T00:50:26.377 に答える
2

モンキーパッチは注意して使用する必要があることに同意しますが、場合によっては意味があります。active_support ライブラリの一部である 5.days.ago を入力できるヘルパーが本当に気に入っています

したがって、この場合、他の答えのいくつかがより良いかもしれませんが、Ruby クラスを拡張している場合は、すべての拡張機能を lib/extensions/class_name.rb に保持します。

このようにして、プロジェクトに取り組んでいるときに、標準クラスでは通常とは異なる可能性があるものをすばやく簡単に見つけて確認できます。

于 2008-11-06T20:25:51.823 に答える
0

質問が古いことに気付きますが、最も明確な方法は、 と の 2 つの属性@lengthを持つ Distance クラスを作成することだと思います@unit

おそらく距離のクラス変数として、変換ハッシュが必要です。

class Distance

  @@conversion_rates = {
    meters: {
      feet: 3.28084,
      meters: 1.0
    }
  }

  def to(new_unit)
    new_length = @length * @@conversion_rates[@unit][new_unit]
    Distance.new( new_length, new_unit ) 
  end

end

そして、それはちょっと次のようになります:

Distance.new(3, :meters).to(:feet)

私が正直に思うよりも

3.meters.to_feet
于 2013-03-07T11:06:12.873 に答える
-1

これを行う場合は、すべきではありませんが、コードを次の場所に配置します。

config/initializers/add_methods_that_are_naughty_to_numeric.rb

Railsはこれらを自動的に実行します。

于 2008-11-05T21:53:49.430 に答える