| Path: | doc/tutorial_sugar.rdoc |
| Last Update: | Mon Jun 30 19:56:35 +0000 2008 |
This tutorial assumes you are familiar with use of the Runt API to create temporal expressions. If you‘re unfamiliar with how and why to write temporal expressions, take a look at the temporal expression tutorial.
Starting with version 0.7.0, Runt provides some syntactic sugar for creating temporal expressions. Runt also provides a builder class for which can be used to create expressions in a more readable way than simply using :new.
First, let‘s look at some of the new shorcuts for creating individual expressions. If you look at the lib/runt/sugar.rb file you find that the Runt module has been re-opened and some nutty stuff happens when :method_missing is called.
For example, if you‘ve included the Runt module, you can now create a DIWeek expression by calling a method whose name matches the following pattern:
/^(sunday|monday|tuesday|wednesday|thursday|friday|saturday)$/
So
tuesday
is equivalent to
DIWeek.new(Tuesday)
Here‘s a quick summary of patterns and the expressions they create.
| regex: | /^daily_(\d{1,2})_(\d{2})([ap]m)to(\d{1,2})_(\d{2})([ap]m)$/ |
| example: | daily_8_30am_to_10_00pm |
| action: | REDay.new(8,30,22,00) |
| regex: | /^weekly_(sunday|monday|tuesday|wednesday|thursday|friday|saturday)_to_(sunday|monday|tuesday|wednesday|thursday|friday|saturday)$/ |
| example: | weekly_wednesday_to_friday |
| action: | REWeek.new(Wednesday, Friday) |
| regex: | /^monthly_(\d{1,2})(?:st|nd|rd|th)_to_(\d{1,2})(?:st|nd|rd|th)$/ |
| example: | monthly_2nd_to_24th |
| action: | REMonth.new(2,24) |
| regex: | /^yearly_(january|february|march|april|may|june|july|august|september|october|november|december)_(\d{1,2})_to_(january|february|march|april|may|june|july|august|september|october|november|december)_(\d{1,2}) |
| example: | yearly_may_31_to_september_1 |
| action: | REYear.new(May,31,September,1) |
| regex: | /^(sunday|monday|tuesday|wednesday|thursday|friday|saturday)$/ |
| example: | friday |
| action: | DIWeek.new(Friday) |
| regex: | /^(first|second|third|fourth|last|second_to_last)_(sunday|monday|tuesday|wednesday|thursday|friday|saturday)$/ |
| example: | last_friday |
| action: | DIMonth.new(Last,Friday) |
Now let‘s look at the new ExpressionBuilder class. This class uses some simple methods and instance_eval to allow one to create composite tempooral expressions in a more fluid style than :new and friends. The idea is that you define a block where method calls add to a composite expression using either "and", "or", or "not".
# Create a new builder
b = ExpressionBuilder.new
# Call define with a block
expression = d.define do
on REDay.new(8,45,9,30)
on DIWeek.new(Friday) # "And"
possibly DIWeek.new(Saturday) # "Or"
except DIMonth.new(Last, Friday) # "Not"
end
# expression = "Daily 8:45am to 9:30 and Fridays or Saturday except not the last Friday of the month"
Hmmm, this is not really an improvement over
REDay.new(8,45,9,30) & DIWeek.new(Friday) | DIWeek.new(Saturday) - DIMonth.new(Last, Friday)
I know, let‘s try the new constructor aliases defined above!
expression = d.define do
on daily_8_45am_to_9_30am
on friday
possibly saturday
except last_friday
end
Much better, except "on daily…" seems a little awkward. We can use :occurs which is aliased to :on for just such a scenario.
expression = d.define do
occurs daily_8_45am_to_9_30am
on friday
possibly saturday
except last_friday
end
ExpressionBuilder creates expressions by evaluating a block passed to the :define method. From inside the block, methods :occurs, :on, :every, :possibly, and :maybe can be called with a temporal expression which will be added to a composite expression as follows:
Of course it‘s easy to open the builder class and add you own aliases if the ones provided don‘t work for you:
class ExpressionBuilder
alias_method :potentially, :possibly
etc....
end
If there are shortcuts or macros that you think others would find useful, send in a feature request or patch.