# Decorator
Decorators are a feature built on top of ABS' functions -- they're not a type per se but they do have their own syntactic sugar.
A decorator is a function that "wraps" another function, allowing you to enhance the original function's functionality with the decorator's one.
An example could be a decorator that logs how long a function takes to execute, or delays execution altogether.
# Simple decorators
A decorator is a plain-old function that
accepts the original function and returns a new
function that wraps the original one with its
own behaviour. After defining it, you can
"decorate" other functions through the convenient
@
syntax:
f uppercase(fn) {
return f() {
return fn(...).upper()
}
}
@uppercase
f stringer(x) {
return x.str()
}
stringer({}) # "{}"
stringer(12) # "12"
stringer("hello") # "HELLO"
As you see, stringer
's behaviour has been altered:
it will now output uppercase strings.
# Decorators with arguments
As we've just seen, a decorator simply needs to be a function that accepts the original function and returns a new one, "enhancing" the original behavior. If you wish to configure decorators with arguments, it is as simple as adding another level of "wrapping":
f log_if_slow(treshold_ms) {
return f(original_fn) {
return f() {
start = `date +%s%3N`.int()
res = original_fn(...)
end = `date +%s%3N`.int()
if end - start > treshold_ms {
echo("mmm, we were pretty slow...")
}
return res
}
}
}
That's as simple as that: a named function
that returns a new function that executes the
decorated one (original_fn
) and returns its
result, while logging if it takes longer than
a few milliseconds.
Now that we've declared our decorator, it's time
to use it, through the @
notation:
@log_if_slow(500)
f return_random_number_after_sleeping(seconds) {
`sleep $seconds`
return rand(1000)
}
and we can test our decorator has taken the stage:
⧐ return_random_number_after_sleeping(0)
493
⧐ return_random_number_after_sleeping(1)
mmm, we were pretty slow...
371
Decorators are heavily inspired by Python (opens new window) -- if you wish to understand how they work more in depth we'd recommend reading this primer on Python decorators (opens new window).