Tcl removes a level of backslashes when accessing a string as a list

Ryan Schmidt ryandesign at
Sat Feb 2 01:52:54 UTC 2019

You'd think I'd understand tcl's lists and strings by now. But no. A list is a string and a string is a list. Or maybe it isn't.

I'm having trouble with livecheck.regex. Since it's a regular expression, it's pretty common for it to contain backslashes. The backslashes are being removed when I don't expect them to be.

In src/port1.0/livecheck.tcl MacPorts calls [join ${livecheck.regex}]. Why does it do that? I guess it does that so that we can define a regular expression that contains spaces, without having to enclose it in quotes. MacPorts options are lists, so when we write:

livecheck.regex this is a valid regular expression

what we're really setting livecheck.regex to is a list with 6 items. MacPorts helpfully transforms that into a single string for us.

Except that in so doing, it removes one layer of backslashes. Using the tclsh repl we can see that making a string with a backslash works fine:

$ tclsh
% set a {hello\.world}
% puts $a

But if we access it as a list using lindex or join it loses the backslash:

% lindex $a 0
% join $a

Why does accessing a string as a list remove a level of backslashes? According to the portion of this page that I can see without signing in...

..."The key is to not use list commands on arbitrary strings, and use only list commands to build lists." So... should livecheck.tcl not be using join? Should Portfiles specify livecheck.regex as a single string instead of relying on MacPorts to join a multi-item list into a string? And if we fix this, will we have to change the backslashes in every livecheck.regex everywhere?

More information about the macports-dev mailing list