我对 Ruby 还是很陌生(通读 Pickaxe 并且大部分时间都花在irb
了修补 Ruby 的基类。例如:我在这里回答了另一个 Ruby 问题,发帖人想知道如何从DateTime
. 由于DateTime
该类似乎没有提供此功能,因此我发布了一个答案,该答案将修补DateTime
和Fixnum
类作为可能的解决方案。这是我提交的代码:
require 'date'
# A placeholder class for holding a set number of hours.
# Used so we can know when to change the behavior
# of DateTime#-() by recognizing when hours are explicitly passed in.
class Hours
attr_reader :value
def initialize(value)
@value = value
end
end
# Patch the #-() method to handle subtracting hours
# in addition to what it normally does
class DateTime
alias old_subtract -
def -(x)
case x
when Hours; return DateTime.new(year, month, day, hour-x.value, min, sec)
else; return self.old_subtract(x)
end
end
end
# Add an #hours attribute to Fixnum that returns an Hours object.
# This is for syntactic sugar, allowing you to write "someDate - 4.hours" for example
class Fixnum
def hours
Hours.new(self)
end
end
我修补了这些类,因为我认为在这种情况下,它会产生一种清晰、简洁的语法,用于从DateTime
. 具体来说,由于上述代码,您可以执行以下操作:
five_hours_ago = DateTime.now - 5.hours
看起来很漂亮,也很容易理解;但是,我不确定弄乱DateTime
'-
运算符的功能是否是个好主意。
对于这种情况,我能想到的唯一选择是:
DateTime
1. 简单地即时创建一个新对象,在调用中计算新的小时值new
new_date = DateTime.new(old_date.year, old_date.year, old_date.month, old_date.year.day, old_date.hour - hours_to_subtract, date.min, date.sec)
2. 编写一个实用方法,接受 aDateTime
和要从中减去的小时数
基本上,只是方法(1)的包装:
def subtract_hours(date, hours)
return DateTime.new(date.year, date.month, date.day, date.hour - hours, date.min, date.sec)
end
3.添加一个新的方法来DateTime
代替改变现有的行为#-()
也许是DateTime#less
一种可以与Fixnum#hours
补丁一起使用的新方法,以允许这样的语法:
date.less(5.hours)
然而,正如我已经提到的,我采用了修补方法,因为我认为它会产生更具表现力的语法。
我的方法有什么问题吗,或者我应该使用 3 种替代方法中的一种(或我没有想到的另一种)来做到这一点?我感觉打补丁正在成为我解决 Ruby 问题的新“锤子”,所以我想就我是否以“Ruby 方式”做事得到一些反馈。