texp是Jim Weirich开发的Ruby临时表达式库,提供了模块化、可扩展的序列化语言。
临时表达式提供了一种精炼地表达重复性事件的方式。例如,每年的12月25日是圣诞节。一个代表圣诞节的临时表达式会返回真,如果日期是12月25日。
dec25 = Date.parse("Dec 25, 2008")
christmas_texp.includes?(dec25) # => true
christmas_texp.includes?(dec25 + 1) # => false
可以使用运算符组合临时表达式。例如,如果我有一个圣诞节的临时表达式和一个感恩节的临时表达式,我可以将它们合并成一个假日表达式:
holidays_texp = christmas_texp + thanksgiving_texp
TExp
特性
-
基本表达式
- DayOfWeek
- DayOfMonth
- Week
- Month
- Year
-
复合表达式
- AND
- OR
- NOT
- 时间窗口
inspect的描述人类可读
紧凑、可解析的编码
可由用户扩展的临时表达式类型
建构临时表达式的DSL
例子
以下的例子使用了TExp DSL。DSL默认未开启,可以通过以下方式开启:
-
使用全局
texp
方法和块te = texp { day(1) * month("Jan") }
-
在类中include
TExp::DSL
模块include TExp::DSL te = day(1) * month("Jan")
查看TExp::DSL
模块获取所有DSL命令的完整描述。
匹配周一
te = dow(:monday)
te.includes?(Date.parse("Mar 3, 2008")) # => true
te.includes?(Date.parse("Mar 4, 2008")) # => false
te.includes?(Date.parse("Mar 10, 2008")) # => true
# 等价于
te = TExp::DayOfWeek.new(Date::DAYNAMES.index("Monday"))
# 变体
dow("Mon", "Tues") # 周一或周二
匹配三月的任意一天
te = month(:march)
te.includes?(Date.parse("Mar 1, 2008")) # => true
te.includes?(Date.parse("Mar 31, 2008")) # => true
te.includes?(Date.parse("Mar 15, 1995")) # => true
te.includes?(Date.parse("Feb 28, 2008")) # => false
# 等价于
te = TExp::Month.new(3)
# 变体
month(1,2,3) # 一月、二月、三月
month("Nov", "Dec") # 十一月或十二月
匹配情人节
如果你将临时表达式看成日期的集合,那么你可以以有趣的方式组合这些集合。例如,*
运算符会创建两个日期集合的交集,只匹配同时满足两个表达式的日期。
te = day(14) * month("Feb")
te.includes?(Date.parse("Feb 14, 2008")) # => true
te.includes?(Date.parse("Feb 14, 2007")) # => true
# 等价于
te = TExp::And.new(
TExp::DayOfMonth.new(14),
TExp::Month.new(2))
匹配2008年的情人节
te = day(14) * month("Feb") * year(2008)
te.includes?(Date.parse("Feb 14, 2008")) # => true
te.includes?(Date.parse("Feb 14, 2007")) # => false
# 等价于
te = TExp::And.new(
TExp::DayOfMonth.new(14),
TExp::Month.new(2),
TExp::Year.new(2008))
匹配多个日期
交集之外,我们可以请求两个临时表达式的并集。下面我们构建一个匹配圣诞节和新年的临时表达式:
christmas = day(25) * month("Dec")
new_years = day(1) * month("Jan")
holidays = christmas + new_years
holidays.includes?(Date.parse("Jan 1, 2008")) # => true
holidays.includes?(Date.parse("Dec 25, 2008")) # => true
holidays.includes?(Date.parse("Jan 1, 2009")) # => true
holidays.includes?(Date.parse("Feb 14, 2008")) # => false
# 等价于
holidays = TExp::Or.new(
TExp::And.new( TExp::DayOfMonth.new(25), TExp::Month(12) ),
TExp::And.new( TExp::DayOfMonth.new(1), TExp::Month(1) ))
排除日期
除了月末的周五之外的其他周五都是Casual Friday:
fridays = dow(:fri)
last_friday = week(:last) * dow(:fri)
casual_fridays = fridays - last_friday
casual_fridays.includes?(Date.new(2013, 6, 21)) # => true
casual_fridays.includes?(Date.new(2013, 6, 28)) # => false
相关链接
编译 SegmentFault
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。