6.4.8 Internal execute, read
To run a stream of MetaEdit+ command-line operations in this
MetaEdit+ session use:
internal 'forAll:run: WatchFamily Checkings' execute
The
example runs the
forAll:run:
command-line operation with its two arguments, in this case running the
Checkings generator on all instances of WatchFamily. If an argument contains a
space, you can surround that argument in double quotes, as you would on the
command line (a double quote in a quoted argument can be escaped by duplicating
it, e.g.
"use ""scare quotes""
sparingly"). Multiple commands can be executed in one long
space-separated string, just as on the command line. You can find more details
on the available command-line operations in Chapter
10; note that some only make sense before
logging in, and so are not generally usable
here.
internal execute, internal executeBlocking
Note that there is no use here for non-blocking execution, so
the
execute and
executeBlocking closing tags behave
identically, with both blocking.
internal read
Some MetaEdit+ command-line operations return a string, and
the internal..read command can be used
to retrieve that string, e.g. for output or to store in a variable. These
command-line operations are string functions that can return information about
the state of MetaEdit+ or answer questions about the environment. For instance,
you can retrieve the name of the logged in user:
'This generator was run by '
internal 'user' read
Some of the string functions take
string arguments, e.g. a filename whose existence we want to check. The
exists: function returns
'T' for true if the file exists, or an
empty string if not, so it can be used in conditionals:
if __(internal 'exists: name.txt' read) then
@a = __(filename 'name.txt' read)
else
@a = 'unnamed'
endif
For consistency with
internal..execute, multiple operations
can be called inside a single
internal...read. Each string function
result will start on a new line in the output (note that some string function
results may themselves include newlines).
Operations that are not string functions can still be used
in
internal..read. They will run their
command as normal, but will have no effect on the output (not even a new line).
Similarly, string functions can be used in
internal..execute, but their output
will be discarded.
internal read with textForMERL:
A special case worth mentioning is the command-line string
function textForMERL:. When used in
internal..read, this can allow MERL to
generate MERL on the fly and run it. This is generally regarded as a Bad Idea,
and any permanent mental damage caused is at the user’s own risk. On the
face of it, the usage of the command is like any other case:
internal 'textForMERL: "..."' read
Note that the
MERL code to run is enclosed in double quotes (as it will generally include a
space), and the whole command is enclosed in single quotes. Any double quote in
the MERL code must thus be doubled (as must any single quote there in a literal,
as is always the case).
Note that
textForMERL: will not inherit the
current generator context: it is intended for use on the command line, where
there is no context. Context can however be provided by building the MERL to be
run so that it includes Live Code hyperlinks, e.g. something like:
do 'hyperlinkedString' { do contents {...}}
Within
the inner block, we thus have the context of the Live Code target of the
hyperlinked string. For example, to provide the current model element as context
and run the MERL code in @merl in that context:
to '%dblq' newline '" $""' endto
@merl = 'foreach .() { id '': '' type newline }'
internal 'textForMERL: '
'"'
'do ''' oid ''' { do contents {' @merl%dblq '}}'
'"'
read
Of course, nothing stops you from using this
approach recursively: the MERL code that you generate and run could itself
generate MERL code and run it. For further details, see Section
6.4.8.