mirror of https://github.com/deavmi/homepage.git
Compare commits
2 Commits
d0bceedc45
...
c8e63b8082
Author | SHA1 | Date |
---|---|---|
Tristan B. Velloza Kildaire | c8e63b8082 | |
Tristan B. Velloza Kildaire | 87d52986b4 |
|
@ -145,4 +145,180 @@ else
|
|||
ERROR("Could not get a valid project description");
|
||||
return;
|
||||
}
|
||||
```
|
||||
|
||||
## Configuration engine
|
||||
|
||||
TODO: Add this
|
||||
|
||||
## Predicates, Optionals and some tooling
|
||||
|
||||
One of the things that come sup quite a lot when programming
|
||||
and dealing with arrays of data (items of the same data type)
|
||||
is the ability to programatically filter such collections of
|
||||
data by some form of reusable component - enter _the predicate_.
|
||||
|
||||
The predicate is not any sort of new wrapper type I came up
|
||||
with, but rather it is a templatised (type-parameterized) alias
|
||||
which when used, expands into a `bool delegate(T)` - some delegate
|
||||
which takes in a single argument of type `T` and returns a `bool`,
|
||||
a _verdict_.
|
||||
|
||||
The definition is as follows:
|
||||
|
||||
```d
|
||||
/**
|
||||
* Predicate for testing an input type
|
||||
* against a condition and returning either
|
||||
* `true` or `false`
|
||||
*
|
||||
* Params:
|
||||
* T = the input type
|
||||
*/
|
||||
template Predicate(T)
|
||||
{
|
||||
/**
|
||||
* Parameterized delegate pointer
|
||||
* taking in `T` and returning
|
||||
* either `true` or `false`
|
||||
*/
|
||||
alias Predicate = bool delegate(T);
|
||||
}
|
||||
```
|
||||
|
||||
There is also a handy `predicateOf(alias)` template used for
|
||||
constructing predicates from some symbol (either a function
|
||||
or a delegate).
|
||||
|
||||
### Example code
|
||||
|
||||
#### Predicate example
|
||||
|
||||
Suppose we have some function as shown below:
|
||||
|
||||
```d
|
||||
private bool isEven(int number)
|
||||
{
|
||||
return number%2==0;
|
||||
}
|
||||
```
|
||||
|
||||
We can then construct a predicate out of it
|
||||
and test it against some input values:
|
||||
|
||||
```d
|
||||
/**
|
||||
* Uses a `Predicate` which tests
|
||||
* an integer input for evenness
|
||||
*
|
||||
* We create the predicate by
|
||||
* passing in the symbol of the
|
||||
* function or delegate we wish
|
||||
* to use for testing truthiness
|
||||
* to a template function
|
||||
* `predicateOf!(alias)`
|
||||
*/
|
||||
unittest
|
||||
{
|
||||
Predicate!(int) pred = predicateOf!(isEven);
|
||||
|
||||
assert(pred(0) == true);
|
||||
assert(pred(1) == false);
|
||||
|
||||
bool delegate(int) isEvenDel = toDelegate(&isEven);
|
||||
pred = predicateOf!(isEvenDel);
|
||||
|
||||
assert(pred(0) == true);
|
||||
assert(pred(1) == false);
|
||||
}
|
||||
```
|
||||
|
||||
## Delay mechanism
|
||||
|
||||
One of the things I decided to put together was a programming
|
||||
structure that I thought would be usable in a scenario as follows:
|
||||
|
||||
> You have run some task on some remote server and now you want to
|
||||
regularly check in with it and see when a reply is sent back that
|
||||
satisfies some requirement. You _also_ can't do this forever so you
|
||||
want to set an interval for how frequently you re-check and then also
|
||||
a total timeout time which will be your deadline - when you exceed
|
||||
it then you stop checking.
|
||||
|
||||
This mechanism is called the `Delay` and can be found in the
|
||||
`niknaks.mechanisms` package.
|
||||
|
||||
The constructor appears as follows:
|
||||
|
||||
```d
|
||||
/**
|
||||
* Constructs a new delay mechanism
|
||||
* with the given delegate to call
|
||||
* in order to determine the verdict,
|
||||
* an interval to call it at and the
|
||||
* total timeout
|
||||
*
|
||||
* Params:
|
||||
* verdictProvider = the provider of the verdicts
|
||||
* interval = thje interval to retry at
|
||||
* timeout = the timeout
|
||||
*/
|
||||
this(VerdictProviderDelegate verdictProvider, Duration interval, Duration timeout)
|
||||
{
|
||||
this.verdictProvider = verdictProvider;
|
||||
this.interval = interval;
|
||||
this.timeout = timeout;
|
||||
}
|
||||
```
|
||||
|
||||
Therefore you can set those two parameters mentioned earlier. The first
|
||||
parameter is the "check" that is to be periodically called. The delay
|
||||
system will return successfully if at some point this `VerdictProviderDelegate`
|
||||
returns a `true` _within_ the timeout window of `timeout`. If you
|
||||
keep getting `false` returned and go over the `timeout` period then
|
||||
a `DelayTimeoutException` is thrown.
|
||||
|
||||
### Example code
|
||||
|
||||
Here is an example where my verdict function (technically a delegate in
|
||||
the case of a D unittest) which refers to a variable `cnt`. This example
|
||||
illustrates the multiple retry calls to said function due to it only
|
||||
returning a `true` verdict on the _second_ call.
|
||||
|
||||
|
||||
```d
|
||||
/**
|
||||
* Tests out the delay mechanism
|
||||
* with a verdict provider (as a
|
||||
* delegate) which is only true
|
||||
* on the second call
|
||||
*/
|
||||
unittest
|
||||
{
|
||||
int cnt = 0;
|
||||
bool happensLater()
|
||||
{
|
||||
cnt++;
|
||||
if(cnt == 2)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
Delay delay = new Delay(&happensLater, dur!("seconds")(1), dur!("seconds")(1));
|
||||
|
||||
try
|
||||
{
|
||||
delay.go();
|
||||
assert(true);
|
||||
}
|
||||
catch(DelayTimeoutException e)
|
||||
{
|
||||
assert(false);
|
||||
}
|
||||
}
|
||||
```
|
Loading…
Reference in New Issue