source.mvb
works like source(local=TRUE)
, except you can intersperse free-format data into your code. current.source
returns the connection that's currently being read by source.mvb
, so you can redirect input accordingly. To do this conveniently inside read.table
, you can use from.here
to read the next lines as data rather than R code.
source.mvb( con, envir=parent.frame(), max.n.expr=Inf,
echo=getOption( 'verbose'), print.eval=echo,
prompt.echo=getOption( 'prompt'), continue.echo=getOption( 'continue'))
current.source()
from.here( EOF=as.character(NA)) # Don't use it like this!
# Use "from.here" only inside "read.table", like so:
# read.table( file=from.here( EOF=), ...)
a filename or connection
an environment to evaluate the code in; by default, the environment of the caller of source
finish after evaluating max.n.expr
complete expressions, unless file ends first.
line which terminates data block; lines afterwards will again be treated as R statements.
other args to read.table
as per source
source.mvb
returns the value of the last expression executed, but is mainly called for its side-effects of evaluating the code. from.here
returns a connection, of class c( "selfdeleting.file", "file", "connection")
; see Details. current.source
returns a connection.
Because source.mvb
relies on pushBack
, con=stdin()
won't work.
Calls to source.mvb
can be nested, because the function maintains a stack of connections currently being read by source.mvb
. The stack is stored in the list source.list
in the mvb.session.info
environment, on the search path. current.source
returns the last (most recent) entry of source.list
.
The sequence of operations differs from vanilla source
, which parses the entire file and then executes each expression in turn; that's why it can't cope with interspersed data. Instead, source.mvb
parses one statement, then executes it, then parses the next, then executes that, etc. Thus, if you include in your file a call to e.g.
text.line <- readLines( con=current.source(), n=1)
then the next line in the file will be read in to text.line
, and execution will continue at the following line. readLines.mvb
can be used to read text whose length is not known in advance, until a terminating string is encountered; lines after the terminator, if any, will again be evaluated as R expressions by source.mvb
.
After max.n.expr
statements (i.e. syntactically complete R expressions) have been executed, source.mvb
will return.
If the connection was open when source.mvb
is called, it is left open; otherwise, it is closed.
If you want to use read.table
or scan
etc. inside a source.mvb
file, to read either a known number of lines or the rest of the file as data, you can use e.g. read.table( current.source(), ...)
.
If you want to read.table
to read an unknown number of lines until a terminator, you could explicitly use readLines.mvb
, as shown in the demo "source.mvb.demo.R". However, the process is cumbersome because you have to explicitly open and close a textConnection
. Instead, you can just use read.table( from.here( EOF=...), ...)
with a non-default EOF
, as in Usage and the same demo (but see Note). from.here
shouldn't be used inside scan
, however, because a temporary file will be left over.
current.source()
can also be used inside a source file, to work out the source file's name. Of course, this will only work if the file is being handled by source.mvb
rather than source
.
If you type source.list
at the R command prompt, you should always see an empty list, because all source.mvb
calls should have finished. However, the source list can occasionally become corrupt, i.e. containing invalid connections (I have only had this happen when debugging source.mvb
and quitting before the exit code can clean up). If so, you'll get an error message on typing source.list
(?an R bug?). Normally this won't matter at all. If it bothers you, try source.list <<- list()
.
source
, readLines.mvb
, flatdoc
, the demo in "source.mvb.demo.R"
# NOT RUN {
# You wouldn"t normally do it like this:
tt <- tempfile()
cat( "data <- scan( current.source(), what=list( x=0, y=0))",
"27 3",
"35 5",
file=tt, sep="\n")
source.mvb( tt)
unlink( tt)
data # list( x=c( 27, 35), y=c(3, 5))
# "current.source", useful for hacking:
tt <- tempfile()
cat( "cat( \"This code is being read from file\",",
"summary( current.source())$description)", file=tt)
source.mvb( tt)
cat( "\nTo prove the point:\n")
cat( scan( tt, what="", sep="\n"), sep="\n")
unlink( tt)
# }
Run the code above in your browser using DataLab