Ruby臨時表達式模塊:TExp
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 </ul> </li>
-
復合表達式
- AND
- OR
- NOT
- 時間窗口 </ul> </li>
-
inspect的描述人類可讀
</li> -
緊湊、可解析的編碼
</li> -
可由用戶擴展的臨時表達式類型
</li> -
建構臨時表達式的DSL
</li> </ul>例子
以下的例子使用了TExp DSL。DSL默認未開啟,可以通過以下方式開啟:
-
使用全局
texp
方法和塊te = texp { day(1) * month("Jan") }
</li> -
在類中include
TExp::DSL
模塊include TExp::DSL te = day(1) * month("Jan")
</li> </ul>查看
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") # 周一或周二</pre></code>
匹配三月的任意一天
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") # 十一月或十二月</pre></code>
匹配情人節
如果你將臨時表達式看成日期的集合,那么你可以以有趣的方式組合這些集合。例如,
*
運算符會創建兩個日期集合的交集,只匹配同時滿足兩個表達式的日期。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))</pre></code>
匹配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))</pre></code>
匹配多個日期
交集之外,我們可以請求兩個臨時表達式的并集。下面我們構建一個匹配圣誕節和新年的臨時表達式:
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) ))</pre></code>
排除日期
除了月末的周五之外的其他周五都是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</pre></code>
相關鏈接
- 項目主頁
- TExp DSL
- Git倉庫
- Issues/Bugs </ul> 編譯 SegmentFault
-