Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/nteetor/tinsel
Use Decorators to Transform Functions
https://github.com/nteetor/tinsel
decorators function-decorator r
Last synced: 2 months ago
JSON representation
Use Decorators to Transform Functions
- Host: GitHub
- URL: https://github.com/nteetor/tinsel
- Owner: nteetor
- License: other
- Created: 2016-10-28T15:30:33.000Z (about 8 years ago)
- Default Branch: master
- Last Pushed: 2017-09-18T13:32:27.000Z (over 7 years ago)
- Last Synced: 2024-10-25T13:51:13.626Z (3 months ago)
- Topics: decorators, function-decorator, r
- Language: R
- Homepage:
- Size: 126 KB
- Stars: 21
- Watchers: 5
- Forks: 0
- Open Issues: 11
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# tinsel
Decorating functions in R.
![Travis-CI Build Status](https://travis-ci.org/nteetor/tinsel.svg?branch=master) [![codecov](https://codecov.io/gh/nteetor/tinsel/branch/master/graph/badge.svg)](https://codecov.io/gh/nteetor/tinsel) ![cran status](http://www.r-pkg.org/badges/version/tinsel)
The tinsel package adds function decorators to R using a special `#.` comment.
Decorators are a means of transforming a function without needing to rewrite
the function. They allow for easy integration of new code onto existing code. These benefits
are illustrated below with an example about object classes.### What are decorators all about?
Say we develop a *Spaceship* class. In addition to our standard *Spaceship*
class, we also need a class for a spaceship with a hyperdrive. So we develop a
*SpaceshipWithHyperdrive* class. Hoever, given all our spaceships we also need a
mothership. So we develop a *MotherSpaceship*. But, what if the mothership also
has a hyperdrive? In this have to add two new classes, *MotherSpaceship* and
*MotherSpaceshipWithHyperdrive*. While the situation is not unmanageable adding
a new class for each spaceship feature, or even for every couple of features, is
less than ideal.Instead we can create a decorator for each new spaceship feature. Let's call
these decorators *HyperdriveSpaceshipDecorator* and *MotherSpaceshipDecorator*.
The *HyperdriveSpaceshipDecorator* takes the *Spaceship* class, with all the
*Spaceship* methods, and adds hyperdrive-related methods. Thus, we are saved the
trouble of copying over the *Spaceship* methods to a new class as would have
been necessary to create the *SpaceshipWithHyperdrive*, *MotherSpaceship*,
and *MotherSpaceshipWithHyperdrive* classes.### R Decorators (and *your* decorators)
Let's create a function `if_warning` which wraps a function `f` such that if `f(...)`
would generate a warning a default value is returned instead, otherwise `f(...)` is
returned.```R
if_warning <- function(f, default) {
function(...) {
tryCatch(
f(...),
warning = function(w) {
default
})
}
}
```Now let's transform the default `mean` function, so instead of generating a
warning the function returns `Inf`. Great!```R
mean_inf <- if_warning(mean, Inf)# give it a try!
mean_inf(1:5)
mean_inf(c(1, 'two', 3))
```Here is where the special comment `#.` comes in. The above code can be
rewritten as the following,```R
#. if_warning(Inf)
mean_inf <- mean
```The special comment `#.` is used to denote a function decorator. In this
example, `#. if_warning` denotes `if_warning` as the decorator of the decoratee
`mean`. `mean` is passed as the first argument to `if_warning` and `Inf`
as the second argument. The result of transforming `mean` with `if_warning` is
assigned to `mean_inf`.In order to see the decorator annotation example in action, save the above code
in a file, source the file using `source_decoratees`, and then call `mean_inf`
once more. (Gentle reminder, the output is expected to be the same)### Installing tinsel
tinsel is now available on CRAN.
```R
install.packages('tinsel')
```You can install the latest version of tinsel using devtools (currently even with version 0.0.1 on CRAN).
```R
# install.packages('devtools')
devtools::install_github('nteetor/tinsel')
```Check out the `source_decoratees` function to get started.
### RStudio Addin
If you are working in RStudio the tinsel package includes an addin for the core
function `source_decoratees`. To bind the addin to a keyboard shortcut in
RStudio navigate to **Tools** > **Addins** > **Browse Addins** > **Keyboard
Shorcuts**. For more information about the keyboard shortcuts checkout the
RStudio [support
page](https://support.rstudio.com/hc/en-us/articles/206382178-Customizing-Keyboard-Shortcuts).
If you choose to setup a keyboard shortcut for the addin I recommend
Alt+Shift+S since
Cmd+Shift+S (or
Ctrl+Shift+S on Linux and Windows) is the source active file
shortcut. The end result is you can quickly load your decorated functions like
you would source all functions from the active file.---
Cheers, Nate.