runt 0.6.0 → 0.7.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,74 +1,74 @@
1
- #!/usr/bin/env ruby
2
-
3
- require 'date'
4
- require 'runt'
5
-
6
-
7
- module Runt
8
- # :title:DateRange
9
- # == DateRange
10
- #
11
- #
12
- # Based the <tt>range</tt>[http://martinfowler.com/ap2/range.html] pattern by Martin Fowler.
13
- #
14
- #
15
- #
16
- # Author:: Matthew Lipper
17
- class DateRange < Range
18
-
19
- include DPrecision
20
-
21
- attr_reader :start_expr, :end_expr
22
-
23
- def initialize(start_expr, end_expr,exclusive=false)
24
- super(start_expr, end_expr,exclusive)
25
- @start_expr, @end_expr = start_expr, end_expr
26
- end
27
-
28
- def include?(obj)
29
- return super(obj.min) && super(obj.max) if obj.kind_of? Range
30
- return super(obj)
31
- end
32
-
33
- def overlap?(obj)
34
- return true if( member?(obj) || include?(obj.min) || include?(obj.max) )
35
- return true if( obj.kind_of?(Range) && obj.include?(self) )
36
- false
37
- end
38
-
39
- def empty?
40
- return @start_expr >= @end_expr
41
- end
42
-
43
- def gap(obj)
44
-
45
- return EMPTY if self.overlap? obj
46
-
47
- lower=nil
48
- higher=nil
49
-
50
- if((self<=>obj)<0)
51
- lower=self
52
- higher=obj
53
- else
54
- lower=obj
55
- higher=self
56
- end
57
-
58
- return DateRange.new((lower.end_expr+1),(higher.start_expr-1))
59
- end
60
-
61
- def <=>(other)
62
- return @start_expr <=> other.start_expr if(@start_expr != other.start_expr)
63
- return @end_expr <=> other.end_expr
64
- end
65
-
66
- def min; @start_expr end
67
- def max; @end_expr end
68
- def to_s; @start_expr.to_s + " " + @end_expr.to_s end
69
-
70
-
71
- EMPTY = DateRange.new(PDate.day(2004,2,2),PDate.day(2004,2,1))
72
-
73
- end
74
- end
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'date'
4
+ require 'runt'
5
+
6
+
7
+ module Runt
8
+ # :title:DateRange
9
+ # == DateRange
10
+ #
11
+ #
12
+ # Based the <tt>range</tt>[http://martinfowler.com/ap2/range.html] pattern by Martin Fowler.
13
+ #
14
+ #
15
+ #
16
+ # Author:: Matthew Lipper
17
+ class DateRange < Range
18
+
19
+ include DPrecision
20
+
21
+ attr_reader :start_expr, :end_expr
22
+
23
+ def initialize(start_expr, end_expr,exclusive=false)
24
+ super(start_expr, end_expr,exclusive)
25
+ @start_expr, @end_expr = start_expr, end_expr
26
+ end
27
+
28
+ def include?(obj)
29
+ return super(obj.min) && super(obj.max) if obj.kind_of? Range
30
+ return super(obj)
31
+ end
32
+
33
+ def overlap?(obj)
34
+ return true if( member?(obj) || include?(obj.min) || include?(obj.max) )
35
+ return true if( obj.kind_of?(Range) && obj.include?(self) )
36
+ false
37
+ end
38
+
39
+ def empty?
40
+ return @start_expr >= @end_expr
41
+ end
42
+
43
+ def gap(obj)
44
+
45
+ return EMPTY if self.overlap? obj
46
+
47
+ lower=nil
48
+ higher=nil
49
+
50
+ if((self<=>obj)<0)
51
+ lower=self
52
+ higher=obj
53
+ else
54
+ lower=obj
55
+ higher=self
56
+ end
57
+
58
+ return DateRange.new((lower.end_expr+1),(higher.start_expr-1))
59
+ end
60
+
61
+ def <=>(other)
62
+ return @start_expr <=> other.start_expr if(@start_expr != other.start_expr)
63
+ return @end_expr <=> other.end_expr
64
+ end
65
+
66
+ def min; @start_expr end
67
+ def max; @end_expr end
68
+ def to_s; @start_expr.to_s + " " + @end_expr.to_s end
69
+
70
+
71
+ EMPTY = DateRange.new(PDate.day(2004,2,2),PDate.day(2004,2,1))
72
+
73
+ end
74
+ end
@@ -1,141 +1,150 @@
1
- #!/usr/bin/env ruby
2
-
3
- require 'runt'
4
- require 'date'
5
-
6
- module Runt
7
-
8
- # :title:DPrecision
9
- # == DPrecision
10
- # Module providing automatic precisioning of Date, DateTime, and PDate classes.
11
- #
12
- # Inspired by a <tt>pattern</tt>[http://martinfowler.com/ap2/timePoint.html] by Martin Fowler.
13
- #
14
- #
15
- # Author:: Matthew Lipper
16
- module DPrecision
17
-
18
- def DPrecision.to_p(date,prec=DEFAULT)
19
-
20
- case prec
21
- when MIN then PDate.min(*DPrecision.explode(date,prec))
22
- when DAY then PDate.day(*DPrecision.explode(date,prec))
23
- when HOUR then PDate.hour(*DPrecision.explode(date,prec))
24
- when MONTH then PDate.month(*DPrecision.explode(date,prec))
25
- when YEAR then PDate.year(*DPrecision.explode(date,prec))
26
- when SEC then PDate.sec(*DPrecision.explode(date,prec))
27
- when MILLI then date #raise "Not implemented."
28
- else PDate.default(*DPrecision.explode(date,prec))
29
- end
30
- end
31
-
32
- def DPrecision.explode(date,prec)
33
- result = [date.year,date.month,date.day]
34
- if(date.respond_to?("hour"))
35
- result << date.hour << date.min << date.sec
36
- else
37
- result << 0 << 0 << 0
38
- end
39
- result
40
- end
41
-
42
- #Simple value class for keeping track of precisioned dates
43
- class Precision
44
- include Comparable
45
-
46
- attr_reader :precision
47
- private_class_method :new
48
-
49
- #Some constants w/arbitrary integer values used internally for comparisions
50
- YEAR_PREC = 0
51
- MONTH_PREC = 1
52
- DAY_PREC = 2
53
- HOUR_PREC = 3
54
- MIN_PREC = 4
55
- SEC_PREC = 5
56
- MILLI_PREC = 6
57
-
58
- #String values for display
59
- LABEL = { YEAR_PREC => "YEAR",
60
- MONTH_PREC => "MONTH",
61
- DAY_PREC => "DAY",
62
- HOUR_PREC => "HOUR",
63
- MIN_PREC => "MINUTE",
64
- SEC_PREC => "SECOND",
65
- MILLI_PREC => "MILLISECOND"}
66
-
67
- #Minimun values that precisioned fields get set to
68
- FIELD_MIN = { YEAR_PREC => 1,
69
- MONTH_PREC => 1,
70
- DAY_PREC => 1,
71
- HOUR_PREC => 0,
72
- MIN_PREC => 0,
73
- SEC_PREC => 0,
74
- MILLI_PREC => 0}
75
-
76
- def Precision.year
77
- new(YEAR_PREC)
78
- end
79
-
80
- def Precision.month
81
- new(MONTH_PREC)
82
- end
83
-
84
- def Precision.day
85
- new(DAY_PREC)
86
- end
87
-
88
- def Precision.hour
89
- new(HOUR_PREC)
90
- end
91
-
92
- def Precision.min
93
- new(MIN_PREC)
94
- end
95
-
96
- def Precision.sec
97
- new(SEC_PREC)
98
- end
99
-
100
- def Precision.millisec
101
- new(MILLI_PREC)
102
- end
103
-
104
- def min_value()
105
- FIELD_MIN[@precision]
106
- end
107
-
108
- def initialize(prec)
109
- @precision = prec
110
- end
111
-
112
- def <=>(other)
113
- self.precision <=> other.precision
114
- end
115
-
116
- def ===(other)
117
- self.precision == other.precision
118
- end
119
-
120
- def to_s
121
- "DPrecision::#{self.label}"
122
- end
123
-
124
- def label
125
- LABEL[@precision]
126
- end
127
- end
128
-
129
- #Pseudo Singletons:
130
- YEAR = Precision.year
131
- MONTH = Precision.month
132
- DAY = Precision.day
133
- HOUR = Precision.hour
134
- MIN = Precision.min
135
- SEC = Precision.sec
136
- MILLI = Precision.millisec
137
- DEFAULT=MIN
138
-
139
- end
140
-
141
- end
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'runt'
4
+ require 'date'
5
+
6
+ module Runt
7
+
8
+ # :title:DPrecision
9
+ # == DPrecision
10
+ # Module providing automatic precisioning of Date, DateTime, and PDate classes.
11
+ #
12
+ # Inspired by a <tt>pattern</tt>[http://martinfowler.com/ap2/timePoint.html] by Martin Fowler.
13
+ #
14
+ #
15
+ # Author:: Matthew Lipper
16
+ module DPrecision
17
+
18
+ def DPrecision.to_p(date,prec=DEFAULT)
19
+
20
+ case prec
21
+ when MIN then PDate.min(*DPrecision.explode(date,prec))
22
+ when DAY then PDate.day(*DPrecision.explode(date,prec))
23
+ when HOUR then PDate.hour(*DPrecision.explode(date,prec))
24
+ when WEEK then PDate.week(*DPrecision.explode(date,prec))
25
+ when MONTH then PDate.month(*DPrecision.explode(date,prec))
26
+ when YEAR then PDate.year(*DPrecision.explode(date,prec))
27
+ when SEC then PDate.sec(*DPrecision.explode(date,prec))
28
+ when MILLI then date #raise "Not implemented."
29
+ else PDate.default(*DPrecision.explode(date,prec))
30
+ end
31
+ end
32
+
33
+ def DPrecision.explode(date,prec)
34
+ result = [date.year,date.month,date.day]
35
+ if(date.respond_to?("hour"))
36
+ result << date.hour << date.min << date.sec
37
+ else
38
+ result << 0 << 0 << 0
39
+ end
40
+ result
41
+ end
42
+
43
+ #Simple value class for keeping track of precisioned dates
44
+ class Precision
45
+ include Comparable
46
+
47
+ attr_reader :precision
48
+ private_class_method :new
49
+
50
+ #Some constants w/arbitrary integer values used internally for comparisions
51
+ YEAR_PREC = 0
52
+ MONTH_PREC = 1
53
+ WEEK_PREC = 2
54
+ DAY_PREC = 3
55
+ HOUR_PREC = 4
56
+ MIN_PREC = 5
57
+ SEC_PREC = 6
58
+ MILLI_PREC = 7
59
+
60
+ #String values for display
61
+ LABEL = { YEAR_PREC => "YEAR",
62
+ MONTH_PREC => "MONTH",
63
+ WEEK_PREC => "WEEK",
64
+ DAY_PREC => "DAY",
65
+ HOUR_PREC => "HOUR",
66
+ MIN_PREC => "MINUTE",
67
+ SEC_PREC => "SECOND",
68
+ MILLI_PREC => "MILLISECOND"}
69
+
70
+ #Minimun values that precisioned fields get set to
71
+ FIELD_MIN = { YEAR_PREC => 1,
72
+ MONTH_PREC => 1,
73
+ WEEK_PREC => 1,
74
+ DAY_PREC => 1,
75
+ HOUR_PREC => 0,
76
+ MIN_PREC => 0,
77
+ SEC_PREC => 0,
78
+ MILLI_PREC => 0}
79
+
80
+ def Precision.year
81
+ new(YEAR_PREC)
82
+ end
83
+
84
+ def Precision.month
85
+ new(MONTH_PREC)
86
+ end
87
+
88
+ def Precision.week
89
+ new(WEEK_PREC)
90
+ end
91
+
92
+ def Precision.day
93
+ new(DAY_PREC)
94
+ end
95
+
96
+ def Precision.hour
97
+ new(HOUR_PREC)
98
+ end
99
+
100
+ def Precision.min
101
+ new(MIN_PREC)
102
+ end
103
+
104
+ def Precision.sec
105
+ new(SEC_PREC)
106
+ end
107
+
108
+ def Precision.millisec
109
+ new(MILLI_PREC)
110
+ end
111
+
112
+ def min_value()
113
+ FIELD_MIN[@precision]
114
+ end
115
+
116
+ def initialize(prec)
117
+ @precision = prec
118
+ end
119
+
120
+ def <=>(other)
121
+ self.precision <=> other.precision
122
+ end
123
+
124
+ def ===(other)
125
+ self.precision == other.precision
126
+ end
127
+
128
+ def to_s
129
+ "DPrecision::#{self.label}"
130
+ end
131
+
132
+ def label
133
+ LABEL[@precision]
134
+ end
135
+ end
136
+
137
+ #Pseudo Singletons:
138
+ YEAR = Precision.year
139
+ MONTH = Precision.month
140
+ WEEK = Precision.week
141
+ DAY = Precision.day
142
+ HOUR = Precision.hour
143
+ MIN = Precision.min
144
+ SEC = Precision.sec
145
+ MILLI = Precision.millisec
146
+ DEFAULT=MIN
147
+
148
+ end
149
+
150
+ end
@@ -0,0 +1,65 @@
1
+ require 'runt'
2
+
3
+ # Convenience class for building temporal expressions in a more
4
+ # human-friendly way. Used in conjunction with shortcuts defined in the
5
+ # sugar.rb file, this allows one to create expressions like the following:
6
+ #
7
+ # b = ExpressionBuilder.new
8
+ # expr = b.define do
9
+ # occurs daily_8_30am_to_9_45am
10
+ # on tuesday
11
+ # possibly wednesday
12
+ # end
13
+ #
14
+ # This equivalent to:
15
+ #
16
+ # expr = REDay.new(8,30,9,45) & DIWeek.new(Tuesday) | DIWeek.new(Wednesday)
17
+ #
18
+ # ExpressionBuilder creates expressions by evaluating a block passed to the
19
+ # :define method. From inside the block, methods :occurs, :on, :every, :possibly,
20
+ # and :maybe can be called with a temporal expression which will be added to
21
+ # a composite expression as follows:
22
+ #
23
+ # * <b>:on</b> - creates an "and" (&)
24
+ # * <b>:possibly</b> - creates an "or" (|)
25
+ # * <b>:except</b> - creates a "not" (-)
26
+ # * <b>:every</b> - alias for :on method
27
+ # * <b>:occurs</b> - alias for :on method
28
+ # * <b>:maybe</b> - alias for :possibly method
29
+ #
30
+ class ExpressionBuilder
31
+
32
+ include Runt
33
+
34
+ attr_accessor :ctx
35
+
36
+ def initialize
37
+ @ctx = nil
38
+ end
39
+
40
+ def define(&block)
41
+ instance_eval(&block)
42
+ end
43
+
44
+ def on(expr)
45
+ add(expr, :&)
46
+ end
47
+
48
+ def add(expr, op)
49
+ @ctx ||= expr
50
+ @ctx = @ctx.send(op, expr) unless @ctx == expr
51
+ @ctx # explicit return, previous line may not execute
52
+ end
53
+
54
+ def except(expr)
55
+ add(expr, :-)
56
+ end
57
+
58
+ def possibly(expr)
59
+ add(expr, :|)
60
+ end
61
+
62
+ alias_method :every, :on
63
+ alias_method :occurs, :on
64
+ alias_method :maybe, :possibly
65
+ end