A blob is a Binary Large Object, an undigested bunch of stuff.

The S statistical computing language (and R is a dialect of S) is call by value. Every time an object passes through a function call a copy is made. For large objects this may result in severe memory usage problems. Whether this is a defect in the S language or not is a matter of opinion. Call by value is fundamental to the S style. It cannot be changed.

However, it can be worked around, and Luke Tierney put hooks in R to so work around. An R object of class "externalptr" is a pointer to a blob. R itself has no idea what to do with it, but it is an R object like any other. It can be copied (meaning the pointer is copied but not the data it points to), passed to functions, or put into a list. You can do anything with it you can do to any R object except (in R) access the data it points to.

The blob must be created by C code (loaded into R with dyn.load or library), worked on by other C code, and destroyed by C code. In between the calls to C, the "externalptr" object can be passed around in R like any other R object.

This page gives a simple example. The C code for the example is in the file

blob.c

and the R code for the example is in the file

blob.R

Download both files. Compile a shared library using the unix command (I explain running this example for unix or linux only, if you are on Windows, you will have to figure out the Windows equivalent from the Writing R Extensions book)

    R CMD SHLIB blob.c
This should produce a shared library that I will assume is called blob.so (on some unices it would be called blob.sl).

Now start R and load both bits of code with the R commands

    dyn.load("blob.so")
    source("blob.R")

And now we are ready to try it out. The R command

    fred <- blob(10)

creates a blob of 10 random numbers. If you print fred, though, you won't see those random numbers. R will only tell you that fred is an object of class "externalptr". To see what is in the blob, we need to feed the "externalptr" object back to C with

    blub(fred)

We can pass this pointer around.

    sally <- fred
    rm(fred)
    blub(sally)

When (if ever) we remove the last pointer

    rm(sally)

R may garbage collect the pointer, and when that happens the memory used for the blob will be reclaimed. To see that we print something when the garbage collector is called.

    fred <- blob(20, blather = TRUE)
    rm(fred)
    invisible(gc())
The output finalizer ran is printed by code in blob.c when the memory for the blob is freed.