Because of processing tuple by element by element, tried calling for-loop (by fields iterator).
My expectation is that the element in for-loop cannot be assined to (the original object should be read-only and should not be rewritten).
But it seems like going fine.
ex)
var tmp1 = @[1,2,3,4,5]
for x in temp1:
x = 10 # doesn't work <- as expected
var tmp2 = (1,2,3,4,5)
for x in temp2:
x = 10 # works <- ?
echo temp2 # (10,10,10,10,10)
Is this a Nim's specification? (or bug?)
Sorry, I wanted to write a code as below:
var temp2 = (1,2,3,4,5)
for x in temp2.fields:
x = 10
echo temp2
As ignoring my typo, is it correct working?my Nim working on ver.0.19.0 (win: amd64)
Codes as above show (Field0: 10, Field1: 10, Field2: 10, Field3: 10, Field4: 10)
let temp2 = (1,2,3,4,5)
for x in temp2.fields:
x = 10
echo temp2
I am not sure what you need the code to do anyways...
From the documentation, it mentions bug or something https://nim-lang.org/docs/system.html#fields.i%2CT
You can pretty much the same case with this issue https://github.com/nim-lang/Nim/issues/9004
Actually, I'm tring to parse command line params by universal types.
Sample Code is below:
import os
import system
import strutils
import strformat
import typeinfo
import macros
type
CmdParam*[T] = object
keyword: string
parseProc: proc (p: string): T
default: T
defaultFlag: bool
res: seq[T]
macro getAnyType(x: typed): auto =
parseStmt($x.getTypeInst.toStrLit)
proc newCmdParam*(keyword: string, default: auto, parseProc: proc): auto =
proc newCmdParamTypedesc[T](keyword: string, default: T, parseProc: proc (p: string): T): CmdParam[T] =
result.keyword = keyword
result.default = default
result.parseProc = parseProc
result.defaultFlag = false
result = newCmdParamTypedesc[getAnyType(default)](keyword, default, parseProc)
macro len(t: tuple): int =
len(t)
macro extractObjectElementInTuple(definedTpl: typed, objectElementName: static[string]): auto =
var length = len(definedTpl.getTypeInst)
var elemStrSeq: seq[string]
for itr in 0..<length:
elemStrSeq.add($definedTpl.toStrLit & "[" & $itr & "]." & objectElementName)
var command = "(" & elemStrSeq.join(",") & ")"
parseStmt(command)
proc parseCmdLineParamsImpl(cmdParamSeq: seq[string], pre: string, sep: string, params: var tuple): auto =
let length = len(params)
var itr: int
var fixedCmd: string
for cmdParam in cmdParamSeq:
# I feel doubt that
# rewritable tuple members will be yeilded
# in the following for-loop.
for prm in params.fields:
fixedCmd = pre & prm.keyword & sep
if cmdParam.startsWith(fixedCmd):
try:
prm.res.add(prm.parseProc(cmdParam.replace(fixedCmd, "")))
except:
echo "convert error"
for prm in params.fields:
if len(prm.res) == 0:
if prm.defaultFlag:
prm.res = @[prm.default]
result = extractObjectElementInTuple(params, "res")
proc parseCmdLineParams*(cmdParamSeq: seq[string], pre="--", sep=":", cmdParamTuple: var tuple): auto =
parseCmdLineParamsImpl(cmdParamSeq, pre, sep, cmdParamTuple)
## An example from here ##
type
MyType[T] = object
value: T
proc toMyType(p: string): MyType[string] =
result.value = p
proc passString(p: string): string =
p
if isMainModule:
var commandLineParamsSample: seq[string] = "--arg1:999 --arg2:9.99 --arg3:abc --arg4:test".split(" ")
var settings = (newCmdParam("arg1", 0, parseInt),
newCmdParam("arg2", 0.0, parseFloat),
newCmdParam("arg3", "", passString),
newCmdParam("arg4", MyType[string](value:"default"), toMyType)
)
var val = commandLineParamsSample.parseCmdLineParams(cmdParamTuple=settings)
# show
for x in val.fields:
echo x
# @[999]
# @[9.99]
# @["abc"]
# @[(value: "test")]
In my expectation, the yielded value is a copy of the tuple member.
And even if rewrite the value, it will not affect the original tuple.
There is no written description in the document.
Wow, this is what I want to ask this forum!
I'll check it.
The problem of this thread has already committed to official document (thanks @mashingan).
So close this thread.
I'll publish this parse-command-line library, and if I get some problems again, please help in Nim forum!