4 ms·
TCL does not need macros because every function can be a macro. Here is an answer to your question: proc multiline {expr} {uplevel [regsub "\n" $expr " "]
by theamk 5y ago
TCL does not need macros because every function can be a macro. Here is an answer to your question:
proc multiline {expr} {uplevel [regsub "\n" $expr " "]}
Use it as following:
multiline {
set foo [
foofn bar [
barfn baz [
bazfn quz 1
]]]
}
try it in action: https://jdoodle.com/ia/jka https://jdoodle.com/ia/jka
The hardest part to understand when writing TCL "macros", is that it's all strings. You might be used to "inputs are s-expressions" from lisp, or "inputs are closure objects with pointers to code and local variables", but not in TCL. {} produces a string parameter. It is interpreted as an expression to be evaluated in parent context when passed to "uplevel". So "proc" takes 3 strings as arguments, and syntactically no different from "regexp".
- celeritascelery 5y agoBut that won't work if I am using variables correct? because {} does not interpolate.
- theamk 5y agosure it will, "uplevel" will interpolate for you. There is a link to online playground, I encourage you to visit it and try various changes. No installation or signin required.
- celeritascelery 5y agoI stand corrected, it works just as you describe.
- blacksqr 5y agoIt will work because the value passed to proc multiline within the curly braces is treated as a string without substitutions, that value is then passed to the regsub command which replaces all newlines in the string with spaces, then the result is passed to uplevel, which is basically "eval this string in the scope context where multiline was called". It's uplevel that does all the variable substitution, using any values defined in the scope where multiline was executed.
- jjnoakes 5y agoThis is not quite right... First off I think you want "regsub -all ...". Second, since your regsub isn't really replacing newlines (except the first), the example isn't so good - your "set foo ..." works without the multiline proc because the opening square brackets are on the same line as the commands. So this also works: jdoodle.com/ia/jnc Third, if you do change the example so that square brackets are on their own lines, as in the original request, then your version would work (with "regsub -all") but it might strip too much - like newlines inside nested quoting. See, for example: jdoodle.com/ia/jne