前段时间我更改了Join-Object
cmdlet,这似乎导致了一个在我的任何测试中都没有显示的错误。
更改的目标主要是代码最小化并尝试通过准备自定义PSObject并在管道中重复使用来提高性能
由于Join-Object
cmdlet相当复杂,我创建了一个简化的cmdlet来显示具体问题:
(PowerShell版本为:[INFO] Scanning for projects...
[INFO]
[INFO] Using the builder org.apache.maven.lifecycle.internal.builder.singlethreaded.SingleThreadedBuilder with a thread count of 1
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] Building FAM.Automation.Selenium 0.0.1-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[INFO]
[INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ FAM.Automation.Selenium ---
[WARNING] Using platform encoding (Cp1252 actually) to copy filtered resources, i.e. build is platform dependent!
[INFO] Copying 0 resource
[INFO]
[INFO] --- maven-compiler-plugin:3.6.1:compile (default-compile) @ FAM.Automation.Selenium ---
[INFO] Nothing to compile - all classes are up to date
[INFO]
[INFO] --- maven-resources-plugin:2.6:testResources (default-testResources) @ FAM.Automation.Selenium ---
[WARNING] Using platform encoding (Cp1252 actually) to copy filtered resources, i.e. build is platform dependent!
[INFO] Copying 0 resource
[INFO]
[INFO] --- maven-compiler-plugin:3.6.1:testCompile (default-testCompile) @ FAM.Automation.Selenium ---
[INFO] Nothing to compile - all classes are up to date
[INFO]
[INFO] --- maven-surefire-plugin:2.19.1:test (default-test) @ FAM.Automation.Selenium ---
[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 2.201 s
[INFO] Finished at: 2018-03-09T19:02:34+08:00
[INFO] Final Memory: 11M/155M
[INFO] ------------------------------------------------------------------------
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-surefire-plugin:2.19.1:test (default-test) on project FAM.Automation.Selenium: Unable to parse configuration of mojo org.apache.maven.plugins:maven-surefire-plugin:2.19.1:test for parameter suiteXmlFiles: Basic element 'suite' must not contain child elements -> [Help 1]
[ERROR]
[ERROR] To see the full stack trace of the errors, re-run Maven with the -e switch.
[ERROR] Re-run Maven using the -X switch to enable full debug logging.
[ERROR]
[ERROR] For more information about the errors and possible solutions, please read the following articles:
[ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/PluginConfigurationException
)
5.1.16299.248
直接测试输出完全符合我的预期:
Function Test($Count) {
$PSObject = New-Object PSObject -Property @{Name = $Null; Value = $Null}
For ($i = 1; $i -le $Count; $i++) {
$PSObject.Name = "Name$i"; $PSObject.Value = $i
$PSObject
}
}
假设我是否将结果分配给变量(例如Test 3 | ft
Value Name
----- ----
1 Name1
2 Name2
3 Name3
)并不重要,但确实如此:
$a
所以,除了分享这段经历之外,我想知道这是编程缺陷还是PowerShell bug / quirk?
答案 0 :(得分:3)
您的原始方法在概念上确实存在缺陷,因为您多次输出相同的对象,反复修改其属性。
输出中的差异由管道的逐项处理解释:
输出到控制台(通过ft
/ Format-Table
)打印{em>当前状态$PSObject
在每次迭代中,它表明一切都很好。
相比之下,捕获变量会在所有迭代完成后反映$PSObject
的状态,此时它只包含最后次迭代的值,Name3
和3
。
您可以验证输出数组$a
确实引用了相同的自定义对象三次,如下所示:
[object]::ReferenceEquals($a[0], $a[1]) # $True
[object]::ReferenceEquals($a[1], $a[2]) # $True
因此,解决方案是在每次迭代中创建一个独特的[pscustomobject]
实例 :
PSv3 + 提供用于创建自定义对象的语法糖:您可以将哈希表(文字)转换为[pscustomobject]
。由于这也每次都会创建一个新实例,因此您可以使用它来简化您的功能:
Function Test($Count) {
For ($i = 1; $i -le $Count; $i++) {
[pscustomobject] @{ Name = "Name$i"; Value = $i }
}
}
这是您自己的与PSv2兼容的解决方案:
Function Test($Count) {
$Properties = @{}
For ($i = 1; $i -le $Count; $i++) {
$Properties.Name = "Name$i"; $Properties.Value = $i
New-Object PSObject -Property $Properties
}
}