| write_sourceable_function | R Documentation |
write_sourceable_function works like write, to produce a source()-friendly printout of a function. However, for the sake of clarity, any suitable character-vector attribute is printed as a multi-line raw string (see Quotes) wrapped in a call to docattr or to string2charvec, which will turn the string back into a character vector when the file is read back in by source. This hides a lot of ugliness, including escaped special characters and superfluous quotes. Character objects that you want attached to the function (but not inside its code) actually looks like the real thing! (They can be accessed by the function code since they live inside environment(sys.function()).) My own main use is a doc attribute for free-text documentation (which later gets turned into "Rd" format by doc2Rd when I produce my packages, but that's a detail). However, I quite often keep other text snippets too, eg "templates".
Raw strings didn't use to exist in R, so before version 2.10 of mvbutils, the alternative version write.sourceable.function (note the dots) instead relied the contortions of flatdoc and source.mvb and readLines.mvb to trick R into accepting unmodified text. None of that should be necessary now.
Obsolete: if write_sourceable_function is applied to a non-function with a "source" attribute, then just the source attribute is printed; the idea is that this could be read back by source, probably in the course of FF after fixr, to regenerate the non-function object. I don't think it's wise to rely on this....
string2charvec, docattr, and simplest_name_generator are helper functions that you're unlikely to use yourself. For the record, though:
string2charvec turns a string (length-1 non-empty character vector with no attributes) into a character vector, with a new element for every newline. The first element is discarded, because it's usually just a linebreak (perhaps preceded by accidental spaces etc) inserted to let the "real" raw string start on a fresh line. string2charvec is called by docattr which facilitates keeping plain-text documentation directly with the function, as an attribute.
docattr is very similar, but adds an S3 class "docattr". It simplifies the code produced by write_sourceable_function for presenting the plain-text documentation. I don't recommend using docattr for anything except an attribute called "doc" that contains, yes, documenbloodytation.
simplest_name_generator prints an R symbol (a "name") in a way that could appear on the LHS of <symbol> <- 0. If the name is simple, with no funny characters in it, then it's not quoted and is left alone. If it contains mildly strange characters that would cause the unquoted version to not parse, then it's quoted. If it contains characters that would break simple quotes (for example, quotes or backticks!) then it's wrapped in a bullet-proof raw string. "Only the paranoid survive"...
cat_strings_rawly outputs (using cat) a character vector as a single raw string wrapped in a call to docattr (if its argument has class "docattr") or otherwise string2charvec. Thus, source will break up the raw string back into a separate element for each newline. (cat_strings_rawly is probably a bad name for this function, since it actually takes a character vector as input, not a string...). It calls cat directly, so you already need to have directed output to wherever you want, eg via sink.
Some exotic language elements simply cannot be represented in sourceable text: for example, a "hard-coded" environment. A file will still be produced, but it won't work with source. There's no solution to such cases. For example:
f <- function( e=.GlobalEnv) environmentName( e) formals( f)$e <- new.env() tf <- tempfile() write_sourceable_function( f, tf) source( tf) # ... complains about e = <environment>
write_sourceable_function( x, con, append=FALSE,
print.name=FALSE, xn=NULL, prefix_package=TRUE, ...)
string2charvec( string)
simplest_name_generator( x)
cat_strings_rawly( x, prefix_package=TRUE)
x |
function or other object, or the name thereof, that is to be written by |
con |
a connection or filename |
append |
if "con" is not already open, should it be appended to rather than overwritten? |
print.name |
should output start with |
xn |
(string) can set this to be the name of the function if |
... |
ignored, but allows calls that use old |
string |
a string (length-1 character vector), presumably a "raw string" though R doesn't care. |
prefix_package |
Whether to prefix the call to |
If x is unquoted and print.name=TRUE, the name is obtained from deparse( substitute( x)). If x is a character string, the name is x itself and the function printed is get(x).
The criteria for deciding whether to raw-string-ify an attribute are:
it must be mode character
it must have length>1 (otherwise there's little point)
it must not have any attributes, except perhaps an S3 class (e.g. no names, no dim)
it must not contain newline characters (since they would be confused with newlines inserted between elements).
Iff the attribute has S3 class "docattr", then cat_strings_rawly will wrap it in a call to mvbutils::docattr (which will mean it doesn't get full printed out at the console); otherwise, it will be wrapped in a call to mvbutils::string2charvec.
# This is from the examples for 'flatdoc'. It's there to illustrate plain-text documentation,
# but you can see the call to 'docattr' in the middle.
flubbo <- structure( function( x){
## A comment
x+1
}
,doc=docattr( r"-{
flubbo not-yet-in-a-package
'flubbo' is a function! And here is some informal doco for it. Whoop-de-doo!
Thanks to raw strings, which are wonderful (see 'Quotes' for extreeeeemly brief doco):
Look at 'flatdoc' examples for more on raw strings.
}-"))
## Don't run
# Infuriating CRAN check (ie that Don't run is ignored--- WTF?!) means I have to wrap this:
if( FALSE && is_very_annoying( "CRAN")){
write_sourceable_function( write_sourceable_function, "wsf.r")
# To dump all functions and their documentation in a workspace into a single sourceable file:
cat( "", file="allfuns.r")
sapply( find.funs(), write_sourceable_function,
con="allfuns.r", append=TRUE, print.name=TRUE)
# A non-function. Probably don't do this!
scrunge <- c( 1:7, 11)
attr( scrunge, "source") <- c( "# Another way:", "c( 1:4, c( 5:7, 11))")
scrunge # [1] 1 2 3 4 5 6 7 11
write_sourceable_function( scrunge, stdout()) # source
fixr( scrunge) # source
} # if F
## End don't run
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.