ElectricalEngine类响应horsepower消息。因为效率是以百分比计算的,程序员可以错误地用整数而不是浮点数来初始化它。
class ElectricalEngine
attr_reader :volts, :current, :efficiency
def initialize(volts, current, efficiency)
@volts, @current, @efficiency = volts, current, efficiency
end
HP_IN_WATTS = 746
def horsepower
(volts * current * efficiency) / HP_IN_WATTS
end
end
puts ElectricalEngine.new(240, 90, .6).horsepower # correct
puts ElectricalEngine.new(240, 90, 60).horsepower # buggy你将如何处理这种情况?
efficiency重命名为efficiency_as_float以使其更清晰。efficiency重命名为efficiency_as_percent,并调整horsepower的S计算。efficiency方法来检查数据类型并进行相应的转换。efficiency类型,如果它不是浮点数,则引发错误。解决方案四可能是这样的。当然,这种转换也可以在initialize方法中进行,但我认为这更简洁。
def horsepower
(volts * current * efficiency_as_float) / HP_IN_WATTS
end
def efficiency_as_float
if efficiency.is_a?(Integer) # what if 1 is passed in instead of 1.0?
efficiency / 100.to_f
else
efficiency
end
end解决方案5如下所示:
def initialize(volts, current, efficiency)
raise "Efficiency must be a float" unless efficiency.is_a?(Float)
@volts, @current, @efficiency = volts, current, efficiency
endElectricalEngine是否有责任转换不正确的数据类型?
发布于 2014-11-18 14:08:24
我想选择#1:什么都不做(除了,正如m_x所说,使用to_f)。但是,如果你真的,真的想做些什么,选择第5条:引发一个错误。具体来说,我建议使用一条有用的消息来引发RangeError。
raise RangeError, "efficiency must be between 0 and 1" unless (0..1).cover?(efficiency.to_f)至于这一点:
因为效率是以百分比计算的,程序员可以错误地用整数而不是浮点数来初始化它。
是的,这是有可能发生的(我自己也犯过这样的错误),但使用0..1浮点数是更常见的方法(在我的经验中)。通常只有电子表格处理百分比为0..100;在大多数编程(和数学)上下文中,“百分比”意味着大约0..1数字。因此,将其称为efficiency_as_percent可能会产生相反的效果:在需要int的地方传递0..1浮点数。
无论哪种方式,效率并不是特定的百分比(尽管您可能会将其作为百分比);它只是一个比率。一个因素。因此,浮动更有意义,因为它们允许您设置比0..100更精确的值。
当然,对于所有这些,您必须有点务实,这样才不会在动态类型的语言中实现严格的类型。例如,您还可以检查volts和current --例如,它们可能不应该是负的。但很快就变成了一个令人头痛的问题。
你也可能会问,“如果我想计算一个超统一引擎的马力呢?”如果efficiency不能超过1.0,你就不能。但从某种意义上说,这只是代数。你有一个公式,你可以插上你想要的任何东西。插入某些值是否有意义并不会改变数学。从实际的角度来看,200%的效率引擎当然是不可能的,但是你仍然可以把数学做得很好。见鬼,即使是一个完美的,100%效率的引擎也是不可能的。所以你应该只允许0.1(半开放范围)吗?如果您不允许1.0本身,那么您允许的值有多近? 0.9? 0.99999?
同样,零效率引擎听起来像是一个错误,那么你也应该指出这一点吗?等等等等..。
无论如何,我可以检查efficiency,但我自己也不会为此烦恼。让程序员来做正确的事情或者承担后果。垃圾进入,垃圾输出。
发布于 2014-11-18 13:44:52
我的两分钱:用鸭子打字。
@efficiency = efficiency.to_f..。如果它像浮子一样嘎嘎作响,那么它就是浮子。这样就可以利用红宝石的威望来达到以下目的:
class EfficiencyProfile
def initialize(some_data, value)
@data = some_data
@efficiency_value = some_value
end
def to_f
@efficiency_value.to_f
end
end
e = EfficiencyProfile.new(some_big_chunk_of_data_about_engine_performance, 42)
ElectricalEngine.new(1,2,e) # would work without a complain动态输入当然是危险的,但是如果您想从中受益,就必须接受它。
显式检查类型是一个半自动的解决方案,因为:
https://codereview.stackexchange.com/questions/70175
复制相似问题