This is my first post featuring the Racket language. At some point we may start evangelizing and looking down our nose at people who don’t leave in the superfluous parentheses, but for now let’s keep it light. Even still, this is not a Racket or Lisp tutorial. If the sight of (sqrt (+ (* 3 4) (* 6 7))))
scares you, run away!
Every time I learn a new language it is always the same:
- learn the basic syntax
- search on how to concatenate a string
- search on how to open and read a file
- search on how to read and write JSON
And so on. Invariably one also comes to “how do I read argv
?” This is that simple post for Racket.
For the equivalent of Python’s sys.argv[1]
or Perl’s $ARGV[0]
, we can do this:
1 2 3 4 5 6 |
#!/usr/bin/env racket #lang racket (define fname (vector-ref (current-command-line-arguments) 0)) (printf "Opening file ~a\n" fname) |
There’s a lot going on here if you’ve never read Lisp or Racket before. current-command-line-arguments
returns a vector (not a list) of the arguments passed on the command. We only want the first argument, and Racket doesn’t provide the filename of the script, so the counting starts at zero. vector-ref
returns that first element. We bind that to fname
and there you have it.
That’s nice and all, but what if there’s no argument supplied on the command line? Let’s try this:
1 2 3 4 5 6 7 8 9 10 |
#!/usr/bin/env racket #lang racket (define fname (cond [(= 0 (vector-length (current-command-line-arguments))) (error "No filename given!") (exit)] [else (vector-ref (current-command-line-arguments) 0)])) (printf "Opening file ~a...\n" fname) |
Trickier, indeed.
We’re still going to bind fname
, and perhaps there is a bit of cheating with the use of (exit)
, but with the cond
routine we’ll test if the vector is zero length and if so, bail. Otherwise the else
clause is triggered and fname
will get the value of the clause.