How do you call a function in Powershell with variable argument list -
i have powershell function 8 parameters. 2 mandatory , 2 mutually exclusive. gives me 24 permutations of function call.
it seems should able craft string based on presence of parameter data , execute string call function, haven't hit upon solution.
this xml input, parameters in brackets [] optional, | means either/or:
<textinsert targetfile="" startstring="" [includestartstring="true"] [endstring="" [includeendstring="true"]] [sourcefile=""|inserttext=""] [ignorecase="true"] />
i had tried constructing function call catenating variables call discovered, this:
function makeinserttextfunctioncalli { param ( [system.xml.xmlelement]$params ) $ignorecase = $params.ignorecase $startstring = $params.startstring $includestart = $params.includestartstring $endstring = $params.endstring $includeend = $params.includeendstring $targetfile = $params.targetfile $inserttext = $params.inserttext $sourcefile = $params.sourcefile # section ############################################################# $cmdstr = "inserttext -file $targetfile -startstring $startstring" if($includestart) { $cmdstr += " -includestartstring" } if($sourcefile) { $cmdstr += " -sourcefile $sourcefile" } else { $cmdstr += " -inserttext $inserttext" } if($endstring) { $cmdstr += " -endstring $endstring" if($includeend) { $cmdstr += " -includeendstring" } } if($ignorecase) { $cmdstr += " -ignorecase" } # $cmdstr # & $cmdstr invoke-expression $cmdstr
but couldn't work. tried 3 variations of calling function. of problems involved embedded quotes in arguments. issue i'm using edit markup language files there's lot of embedded <>" , such symbols. resulting in error last attempt: invoke-expression : '<' operator reserved future use.
the following section of code, inelegant , unsupportable is, work:
# section b ############################################################ #possible parameters $ctargetfile = [convert]::toint32("10000000",2) #128 $cstartstring = [convert]::toint32("01000000",2) #64 $cincludestart = [convert]::toint32("00100000",2) #32 $csourcefile = [convert]::toint32("00010000",2) #16 $cinserttext = [convert]::toint32("00001000",2) #8 $cendstring = [convert]::toint32("00000100",2) #4 $cincludeend = [convert]::toint32("00000010",2) #2 $cignorecase = [convert]::toint32("00000001",2) #1 $parammask = 0 if($ignorecase) { $parammask += $cignorecase } if($startstring) { $parammask += $cstartstring } if($includestart) { $parammask += $cincludestart } if($sourcefile) { $parammask += $csourcefile } if($inserttext) { $parammask += $cinserttext } if($endstring) { $parammask += $cendstring } if($includeend) { $parammask += $cincludeend } if($targetfile) { $parammask += $ctargetfile } switch($parammask) { 192 { inserttext -file $targetfile -startstring $startstring -sourcefile $sourcefile } 193 { inserttext -file $targetfile -startstring $startstring -sourcefile $sourcefile -ignorecase } 200 { inserttext -file $targetfile -startstring $startstring -inserttext $inserttext } 201 { inserttext -file $targetfile -startstring $startstring -inserttext $inserttext -ignorecase } . . <some of 24 permutations removed brevity> . 246 { inserttext -file $targetfile -startstring $startstring -includestart -endstring $endstring -includeend -sourcefile $sourcefile } 247 { inserttext -file $targetfile -startstring $startstring -includestart -endstring $endstring -includeend -sourcefile $sourcefile -ignorecase } 238 { inserttext -file $targetfile -startstring $startstring -includestart -endstring $endstring -includeend -inserttext $inserttext } 239 { inserttext -file $targetfile -startstring $startstring -includestart -endstring $endstring -includeend -inserttext $inserttext -ignorecase } default { #then log invalid parameters error} }
i section b unsupportable because if wants add parameter function, calculating bit mask , entering new permutation in switch statement overly time consuming; opposed adding 1 more catenation section a.
does have tips simplifying code? or critique section might improve it's workability?
mjolinor provided answer. hash splatting works. here's final working code.
$paramhash = @{} if($ignorecase) { $paramhash.add("-ignorecase",$true) } if($startstring) { $paramhash.add("-startstring","$startstring") } if($includestart) { $paramhash.add("-includestartstring",$true) } if($sourcefile) { $paramhash.add("-sourcefile","$sourcefile") } if($inserttext) { $paramhash.add("-inserttext","$inserttext") } if($endstring) { $paramhash.add("-endstring","$endstring") } if($includeend) { $paramhash.add("-includeendstring",$true) } if($targetfile) { $paramhash.add("-file","$targetfile") } inserttext @paramhash
nice, neat, compact, , readable. @mjolinor.
Comments
Post a Comment