Scriptlike: New lib to aid in writing script-like programs

Vladimir Panteleev vladimir at thecybershadow.net
Tue Feb 11 14:01:39 PST 2014


On Tuesday, 11 February 2014 at 11:38:06 UTC, Nick Sabalausky 
wrote:
> I've released a little one-module utility, Scriptlike, to help 
> simplify writing shell script-like programs in D:
>
>   https://github.com/Abscissa/scriptlike

I've been thinking of creating something with a similar purpose, 
however also remove the need for any import lines or declaring a 
main() function, so you can start writing statements from an 
empty file. It would use a different file extension.

Alternatively, you could do what vibe.d does and move the main() 
function to the library. That allows the library to parse 
command-line arguments, or catch the Fail exception (see below).

> - A thin wrapper over std.path and std.file that provides a 
> dedicated Path type specifically designed for managing file 
> paths in a simple, reliable, cross-platform way. No more 
> dealing with slashes, paths-with-spaces, calling buildPath, 
> normalizing, or getting paths mixed up with ordinary strings.

I think this is subjective. Path objects add too much syntax 
overhead, especially in shell script substitutes, IMO.

> - Less-pedantic filesystem operations for when you don't care 
> whether it exists or not: existsAsFile, existsAsDir, 
> existsAsSymlink, tryRename, trySymlink, tryCopy, tryMkdir, 
> tryMkdirRecurse, tryRmdir, tryRmdirRecurse, tryRemove: All 
> check whether the source path exists and return WITHOUT 
> throwing if there's nothing to do.

I think creating a new family of functions is not the best way to 
do this. How about a function/template that wraps a function 
instead? In Phobos, we have collectException(fun(...)), but 
something shorter like attempt!fun(...) would be better for 
scripting.

The biggest advantage to this approach is that such wrappers are 
composable. For example, in my library I have safeUpdate, which 
wraps a function that creates a file by redirecting its output to 
a temporary file, then replacing the target atomically with one 
rename() call, and obtainUsing, which skips the operation 
entirely if the target file already exists (useful for expensive 
operations such as downloading a file). The latter implies the 
former, so that e.g. a program terminated in the middle of the 
download does not consider that file to have been downloaded 
successfully in the previous invocation.

> - One simple call, runShell, to run a shell command 
> script-style (ie, synchronously with forwarded stdout/in/err) 
> from any working directory. (Also automatically works around 
> DMD #10863 without waiting for v2.066 - BTW, thanks all 
> involved who fixed that.)

Sorry about breaking it in the first place ;)

But I would avoid running things "shell-like" though, as it's a 
mess of whitespace/escaping. Passing arguments as an array rather 
than a string is much better for many reasons.

> - One simple function, fail(string msg), to help you exit with 
> an error message in an exception-safe way. (Does require some 
> minor boilerplate added to your main().)

I think this idea combines even better when the main() function 
is created for you.


More information about the Digitalmars-d-announce mailing list