Ankit Shubham
Ankit Shubham

Reputation: 3639

Pass two arguments from command line in sml

I want to pass two arguments from command line. I know how to pass one argument using CommandLine.arguments .

val arg1 = CommandLine.arguments();

But how to pass two arguments and use it?

Thank you.

Upvotes: 0

Views: 744

Answers (3)

Ankit Shubham
Ankit Shubham

Reputation: 3639

I figured it out: Just use

sml "file.sml" "arg1" "arg2"

where arg1 and arg2 are stored in a list and can be extracted in program using "tl" and "hd" function of list.

Upvotes: 0

sshine
sshine

Reputation: 16145

As John says, since CommandLine.arguments : unit -> string list, you can extract both the first and the second argument by regular pattern matching on this list. Assuming the two first arguments can be named foo and bar, and should both be interpreted as strings, and that any other number of arguments (0, 1, 3, ...) is an error, you could write:

fun main () =
    let val (foo, bar) = case CommandLine.arguments () of
                              [foo, bar] => (foo, bar)
                            | _ => raise Fail "Usage: tool <foo> <bar>"

    in ...
    end

And performing transformations on foo and bar, such as conversion to numbers, is not terribly difficult from here. But in case your command-line arguments are optional, or you do not wish for the order of them to matter, or you want to provide multiple ways of specifying them – e.g. -h being an alias for --human-readable while both work – you should consider using a utility library in SML/NJ called GetOpt.

It provides a framework for specifying how command-line arguments should be interpreted in a dynamic way. You can read the SML/NJ GetOpt documentation, which provides a small example. It is a quite generic library and adds some complexity that is perhaps not warranted until you have quite many arguments and cannot be bothered to handle all legal combinations of them.

Upvotes: 4

John Coleman
John Coleman

Reputation: 52008

The type of CommandLine.arguments is

unit -> string list

It doesn't return a single string, it returns a list of strings. Any passed argument will be in the list. You just have to extract them.

If you are passing a single string which splits into multiple arguments with something other than a space as a delimiter you could use String.tokens on it. For example,

String.tokens (fn c => c = #"|") "abc|de|fgh";

Which yields ["abc","de","fgh"]. You need to pass to String.tokens a Boolean-valued function which can tell when a character is a delimiter.

Upvotes: 3

Related Questions