Basic string formatting with NIM
Asked Answered
I

2

7

I am trying to do some very basic string formatting and I got immediately stuck.

What is wrong with this code?

import strutils
import parseopt2

for kind, key, val in getopt():
    echo "$1 $2 $3" % [kind, key, val]

I get Error: type mismatch: got (TaintedString) but expected 'CmdLineKind = enum' but I don't understand how shall I fix it.

Idzik answered 27/2, 2017 at 11:7 Comment(0)
S
6

If you use the strformat Nim-inbuilt library, the same code snippet can be more concise:

import parseopt # parseopt2 has been deprecated!
import strformat

for kind, key, val in getopt():
    echo fmt"{kind} {key} {val}"

Also note that parseopt replaces the deprecated parseopt2 library, at least as of today on Nim 0.19.2.

Shayshaya answered 4/2, 2019 at 21:27 Comment(4)
is it possible to have the string in a variable? I'm thinking of a longer string than "{kind} {key} {val}".Shrine
@Shrine No, the fmt arg needs to be a string literal.Shayshaya
This doesn't answer the question ... zah's answer does.Luiseluiza
@Shrine Then use strutils.% as in OP's code but with the arguments stringified (see zah's answer), or use strutils.format which automatically stringifies them.Luiseluiza
B
9

The problem here is that Nim's formatting operator % expects an array of objects with the same type. Since the first element of the array here has the CmdLineKind enum type, the compiler expects the rest of the elements to have the same type. Obviously, what you really want is all of the elements to have the string type and you can enforce this by explicitly converting the first paramter to string (with the $ operator).

import strutils
import parseopt2

for kind, key, val in getopt():
  echo "$1 $2 $3" % [$kind, key, val]

In case, you are also wondering what is this TaintedString type appearing in the error message, this is a special type indicating a non-validated external input to the program. Since non-validated input data poses a security risk, the language supports a special "taint mode", which helps you keep track of where the inputs may need validation. This mode is inspired by a similar set of features available in the Perl programming language:

http://docstore.mik.ua/orelly/linux/cgi/ch08_04.htm

Barham answered 27/2, 2017 at 11:40 Comment(2)
Ah, an actual answer to the question, which the accepted "answer" isn't.Luiseluiza
Also, format("$1 $2 $3", kind, key, val) auto stringifies the arguments.Luiseluiza
S
6

If you use the strformat Nim-inbuilt library, the same code snippet can be more concise:

import parseopt # parseopt2 has been deprecated!
import strformat

for kind, key, val in getopt():
    echo fmt"{kind} {key} {val}"

Also note that parseopt replaces the deprecated parseopt2 library, at least as of today on Nim 0.19.2.

Shayshaya answered 4/2, 2019 at 21:27 Comment(4)
is it possible to have the string in a variable? I'm thinking of a longer string than "{kind} {key} {val}".Shrine
@Shrine No, the fmt arg needs to be a string literal.Shayshaya
This doesn't answer the question ... zah's answer does.Luiseluiza
@Shrine Then use strutils.% as in OP's code but with the arguments stringified (see zah's answer), or use strutils.format which automatically stringifies them.Luiseluiza

© 2022 - 2024 — McMap. All rights reserved.