在Rails中向Integer类添加方法的最佳位置在哪里?

在Rails中向整数类添加方法的最佳位置在哪里? 我想添加一个to_metersto_miles方法。

如果你的心脏设置与数字(或整数等)类进行混淆以获得单位转换,那么至少要逻辑地并且具有一些实际价值。

首先,创建一个Unit类,用于存储单位类型(米,英尺,立方等)和创建时的值。 然后向Numeric添加一组与单元可以具有的有效值对应的方法:这些方法将返回一个Unit对象,其类型记录为方法名称。 Unit类将支持一堆to_ *方法,这些方法将转换为具有相应单位值的另一个单元类型。 这样,您可以执行以下命令:

 >> x = 47.feet.to_meters => 14.3256 >> x.inspect => # 

处理它的最佳方法可能是Unit类中的转换类型和表达式矩阵,然后使用method_missing检查给定类型是否可以转换为另一种类型。 在numeric类中,使用method_missing询问Unit是否支持给定方法作为单元类型,如果是,则使用numeric作为其值返回所请求类型的单元对象。 然后,您可以通过向Unit添加register_type和register_conversion类方法来支持在运行时添加单位和转换,扩展转换矩阵并且Numeric将“自动”获取该function。

至于放置它的位置,创建一个lib / units.rb文件,该文件也包含Monkey_patch到Numeric,然后在config / environment.rb中初始化它需要lib / units.rb文件。

创建自己的模块/库,在需要它执行此任务时将其包含在范围内。

比如“要求’unitCoversions’”

如果你看起来足够努力,有人已经这样做了:)

然而, DONT尝试修改本机核心类,这只会在Misery中结束。

(此外,您要扩展的类是’数字’,它将适用于整数和浮点数:))

不完全清楚为什么我不应该这样做…… Rails对字符串类做了很大的成功。

因为它可以做到并不意味着它应该被完成。 众所周知,“猴子修补”会产生各种奇怪的副作用,如果做错了,它们就会成为史诗般的失败。

当没有好的替代方案时这样做。

因为如果你真的想要做一些愚蠢的事情,你可以构建一个完整的框架,它所做的只是猴子修补核心类。

例如,在其头部翻转数据库。

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

等等有多少不好的方法没有限制。

 "Bob".createUser(); 

一杯苦难。

如果你想做一些实际的事情,有一个Convert类或函数,

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

至少你没有以这种方式污染全局命名空间和核心function,而且它更具连贯性。

为什么不呢:

 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 

我同意猴子补丁应该小心使用,但偶尔它只是有意义。 我非常喜欢帮助您键入5.days.ago的助手,它们是active_support库的一部分

因此,在这种情况下,其他一些答案可能会更好,但如果您要扩展ruby类,我们将所有扩展保留在lib / extensions / class_name.rb中

这样,在处理项目时,可以快速轻松地找到并查看标准类可能与众不同的任何内容。

通常(和逻辑上),整数不能转换为里程或米。 听起来你可能想要创建一个新的类,如“Feet”或“inches”,用一个整数初始化,然后包含size_in_miles或size_in_meters等方法。 为方便起见,这些方法可以返回decimal或float类型,但您可能还想写一个里程类或米类。

作为替代方法,您可能希望在新类中创建一个具有如下签名的静态方法:

Float feetToMiles(integer I)

那你打电话

miles = Feet.feetToMiles(5280);

并获得miles = 1.0

意识到这个问题已经过时了,但我认为最明确的方法是创建一个具有两个属性@length@unit的Distance类。

你只需要一个转换哈希,可能是Distance的一个类变量:

 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 

如果你打算这样做,你不应该这样做,那么你会把你的代码放入:

 config/initializers/add_methods_that_are_naughty_to_numeric.rb 

Rails会自动为你运行这些。