Version 16 of file join

Updated 2003-08-28 10:03:25

The [file join] command joins zero or more strings with the correct platform-dependent separators so that the result can be interpreted as a path name.


One useful application is to "normalize" a Windows pathname with backslashes to slashes, which is more robust in all kinds of intermediate processing, where substitution might occur:

 % file join {\foo\bar\grill}
 /foo/bar/grill

Back the other way with file nativename:

 % file nativename /foo/bar/grill
 \foo\bar\grill

DGP...but [file normalize] is a better tool for that purpose now.


One way to convert a file type from (possibly) relative to absolute is this:

  set filename [file join [pwd] $filename]

Note that you never need to use cd, and it is best if you don't except in response to user action. Otherwise you just confuse your users... :^/

DKF


MSW The most wonderful property about file join though is that it's so useless on lists that it hurts.

 puts [file join [file split a/b/c]]
 => a b c

I've been bitten by that more than once (e.g. when pruning away common parent-trees in paths, idea:

 set path a/b/c/d/e/f/g; set common_length 3
 set path [file join [lrange [file split $path] $common_length end]]
 => d e f g
 NOT d/e/f/g!!

...it just stinks. *cry* You end up using file split, join $path /, instead. Of course that means you're using native directory separators, which stinks nearly more ... but works. And honestly, I hate to use eval for list splicing :) Basically I don't want to splice the list, file join should just work!

RS It works as documented. You want a different behavior, that it joins the elements of a list. But this can lead to ambiguities, consider

 file join "C:/Program Files/Tcl"

which can be seen as a 2-element list... Also, you don't have to name the separator, Tcl knows:

 % join {foo bar grill} [file separator]
 foo\bar\grill

MSW True, I've stumbled over that so often though .. *mutter*

 % file separator
 bad option "separator": must be atime, attributes, channels, copy, delete, dirname,
 executable, exists, extension, isdirectory, isfile, join, lstat, mtime, mkdir, nativename, 
 owned, pathtype, readable, readlink, rename, rootname, size, split, stat, tail, type, 
 volumes, or writable

RS Well, yes, new feature, 8.4.2 has it. You can always fall back to

 proc file'separator {} {
    switch -- $::tcl_platform(platform) {
        unix    {return /}
        windows {return \\}
        default {error "unknown platform"}
    }
 }

MSW 8.4 is not an option for me (yet) as tix won't work with it, and all the CONSTifying shoots in my C-linkage heritage ... You don't like macintosh, eh ? :) But well, the ambigious list/string problem haunts us in tcl all the time... Even [list "a b"] ends up as a two element list (even though list clearly should create a one element list whose element can be interpreted as two elemen list ..). Ah well ...


Category Command ... well subcommand of file | Category Example