Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Namespaces without packages

Tags:

In reorganising my code base I’d like to clean up my code sharing mechanism. So far I’m using source for lots of small, largely self-contained modules of functionality.

However, this approach suffers from a number of problems, among them

  • the lack of tests for circularity (accidental circular source chains),
  • complex syntax required to properly specify include paths (chdir=TRUE argument, hard-coded paths),
  • potential of name clashes (when redefining objects).

Ideally I’d like to get something alike to the Python module mechanism. The R package mechanism would be overkill here: I do not want to generate nested path hierarchies, multiple files with tons of metadata and manually build the package just to get a small, self-contained, reusable code module.

For now I’m using a code snippet which allows me to solve the first two problems mentioned above. The syntax for inclusion is like this:

import(functional) import(io) import(strings) 

… and a module is defined as a simple source file which resides in the local path. The definition of import is straightforward but I cannot solve the third point: I want to import the module into a separate namespace but from what I see the namespace lookup mechanism is pretty hard-wired to packages. True, I could override `::` or getExportedValue and maybe asNamespace and isNamespace but that feels very dirty and has the potential of breaking other packages.

like image 440
Konrad Rudolph Avatar asked Apr 03 '13 13:04

Konrad Rudolph


People also ask

What are namespace packages?

Each sub-package can now be separately installed, used, and versioned. Namespace packages can be useful for a large collection of loosely-related packages (such as a large corpus of client libraries for multiple products from a single company).

How do you add a namespace in Python?

So if you want to create a namespace, you just need to call a function, instantiate an object, import a module or import a package. For example, we can create a class called Namespace and when you create an object of that class, you're basically creating a namespace.

How do I use a namespace package in Python?

On Python 3.3 you don't have to do anything, just don't put any __init__.py in your namespace package directories and it will just work. On pre-3.3, choose the pkgutil. extend_path() solution over the pkg_resources.

What is an org namespace?

A namespace is a 1–15 character alphanumeric identifier that distinguishes your package and its contents from other packages in your customer's org. A namespace is assigned to a package at the time that it's created, and can't be changed.


1 Answers

Here's a function that completely automates package creation, compilation, and reloading. As others have noted, the utility functions package.skeleton() and devtools::load_all() already get you almost all the way there. This just combines their functionality, using package.skeleton() to create the source directory in a temp directory that gets cleaned up when load_all() is done processing it.

All you need to do is point to the source files from which you want to read in functions, and give the package a name: import() does the rest for you.

import <- function(srcFiles, pkgName) {     require(devtools)     dd <- tempdir()     on.exit(unlink(file.path(dd, pkgName), recursive=TRUE))     package.skeleton(name=pkgName, path = dd, code_files=srcFiles)     load_all(file.path(dd, pkgName)) }  ## Create a couple of example source files cat("bar <- function() {print('Hello World')}", file="bar.R") cat("baz <- function() {print('Goodbye, cruel world.')}", file="baz.R")  ## Try it out import(srcFiles=c("bar.R", "baz.R"), pkgName="foo")  ## Check that it worked head(search()) # [1] ".GlobalEnv"        "package:foo"       "package:devtools" # [4] "package:stats"     "package:graphics"  "package:grDevices" bar() # [1] "Hello World" foo::baz() # [1] "Goodbye, cruel world." 
like image 181
Josh O'Brien Avatar answered Sep 22 '22 02:09

Josh O'Brien