Skip to content

openscienceunil/modulr

Repository files navigation

Build Status Coverage status CRAN_Status_Badge CRAN License Twitter

Modulr: A Dependency Injection Framework for R

Modulr is a Dependency Injection (DI) framework for R which allows to break down sequential programs into discrete, modular units that are loosely coupled, simple to develop, test, debug, maintain, reuse, and share.

  • Modulr is designed to ease production of mocks for testing purpose and is therefore well-suited for test-driven development.
  • Modulr offers docstrings-like comments for documenting the internals of a module.
  • Modulr understands R Markdown and Sweave, thanks to Yihui Xie's knitr package.
  • Modulr takes advantage of semantic versioning to avoid version lock and version promiscuity.
  • Modulr can use GitHub (repositories and gists) to publish and share modules (so-called gears). See modulr/vault for an example.
  • Modulr helps to circumvent errors occurring in a chain of nested dependent modules, showing breadcrumbs.
  • Modulr allows parallelization using futures, thanks to Henrik Bengtsson's future package.
  • Modulr implements package isolation as an experimental feature: following the philosophy of Jim Hester's withr package, the 'with_' method with_no_packages() can be used to run code with temporarily no loaded or attached R packages.

Please read the documentation and vignettes (browseVignettes(package = "modulr")) to see extended examples in action.

"Hello, world!"

library(modulr)

"foo" %provides% "Hello"
#> [2017-06-21T21:58:16 UTC] Defining 'foo' ... OK

"bar" %provides% "World"
#> [2017-06-21T21:58:16 UTC] Defining 'bar' ... OK

"foobar" %requires% list(
  f = "foo", 
  b = "bar"
) %provides% {
  paste0(f, ", ", tolower(b), "!")
}
#> [2017-06-21T21:58:16 UTC] Defining 'foobar' ... OK

make("foobar")
#> [2017-06-21T21:58:16 UTC] Making 'foobar' ...
#> [2017-06-21T21:58:16 UTC] * Visiting and defining dependencies ...
#> [2017-06-21T21:58:16 UTC] * Constructing dependency graph ... OK
#> [2017-06-21T21:58:16 UTC] * Sorting 2 dependencies with 2 relations ... on 1 layer, OK
#> [2017-06-21T21:58:16 UTC] * Evaluating new and outdated dependencies ...
#> [2017-06-21T21:58:16 UTC] ** Evaluating #1/2 (layer #1/1): 'bar' ...
#> [2017-06-21T21:58:16 UTC] ** Evaluating #2/2 (layer #1/1): 'foo' ...
#> [2017-06-21T21:58:16 UTC] DONE ('foobar' in 0.044 secs)
#> [1] "Hello, world!"

Further readings

Installation

install.packages("devtools")
devtools::install_github("hadley/devtools")
devtools::install_github("aclemen1/modulr")

If you encounter a clear bug, please file a minimal reproducible example. For questions and other discussion, please use the modulr mailing list.

Real-world applications

 
This is the dependency graph of a module (on the rightmost side) which exposes tidy, exhaustive, statistics-ready, and daily HR data for the University of Lausanne, Switzerland. Although not visible here, many of these modules are reused in other projects. The University of Lausanne has been running modulr in mission critical applications since March 2015.

Related approaches

In alphabetical order.

  • Rich FitzJohn's remake package.
  • Robert Krzyzanowski's director package.
  • Lev Kuznetsov's injectoR package.
  • Will Landau's drake package.
  • Konrad Rudolph's modules package.
  • Sebastian Warnholz's modules package.

Code of conduct

In order to have a more open and welcoming community, modulr adheres to a Contributor Code of Conduct. Please adhere to this code of conduct in any interactions you have in the modulr community. It is strictly enforced on all official modulr repositories, websites, and resources. If you encounter someone violating these terms, please let the maintainer know and he will address it as soon as possible.

Releases

No releases published

Packages

No packages published

Languages