上次我对 PowerShell 急切展开集合的方式感到困惑时,Keith 总结了它的启发式如下:
Putting the results (an array) within a grouping expression (or subexpression e.g. $()) makes it eligible again for unrolling.
我已将这个建议铭记于心,但仍然无法解释一些深奥的内容。特别是,格式运算符似乎不按规则行事。
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 | filter Identity { $_ } filter Square { ($_, $_) } filter Wrap { (,$_) } filter SquareAndWrap { (,($_, $_)) } $rhs ="a" | Square # 1. all succeed $lhs -f $rhs $lhs -f ($rhs) $lhs -f $($rhs) $lhs -f @($rhs) $rhs ="a" | Square | Wrap # 2. all succeed $lhs -f $rhs $lhs -f ($rhs) $lhs -f $($rhs) $lhs -f @($rhs) $rhs ="a" | SquareAndWrap # 3. all succeed $lhs -f $rhs $lhs -f ($rhs) $lhs -f $($rhs) $lhs -f @($rhs) $rhs ="a","b" | SquareAndWrap # 4. all succeed by coercing the inner array to the string"System.Object[]" $lhs -f $rhs $lhs -f ($rhs) $lhs -f $($rhs) $lhs -f @($rhs) "a" | Square | % { # 5. all fail $lhs -f $_ $lhs -f ($_) $lhs -f @($_) $lhs -f $($_) } "a","b" | Square | % { # 6. all fail $lhs -f $_ $lhs -f ($_) $lhs -f @($_) $lhs -f $($_) } "a" | Square | Wrap | % { # 7. all fail $lhs -f $_ $lhs -f ($_) $lhs -f @($_) $lhs -f $($_) } "a","b" | Square | Wrap | % { # 8. all fail $lhs -f $_ $lhs -f ($_) $lhs -f @($_) $lhs -f $($_) } "a" | SquareAndWrap | % { # 9. only @() and $() succeed $lhs -f $_ $lhs -f ($_) $lhs -f @($_) $lhs -f $($_) } "a","b" | SquareAndWrap | % { # 10. only $() succeeds $lhs -f $_ $lhs -f ($_) $lhs -f @($_) $lhs -f $($_) } |
应用我们在上一个问题中看到的相同模式,很明显为什么像 #1 和 #5 这样的情况表现不同:管道运算符向脚本引擎发出信号以展开另一个级别,而赋值运算符没有。换句话说,位于两个 | 之间的所有内容都被视为一个分组表达式,就像它在 () 中一样。
2 3 4 5 | ("a" | Square).count # explicitly grouped ("a" | Square | measure).count # grouped by pipes ("a" | Square | Identity).count # pipe + () ("a" | Square | Identity | measure).count # pipe + pipe |
出于同样的原因,案例#7 与#5 相比没有任何改进。任何添加额外 Wrap 的尝试都将立即被额外的管道破坏。同上 #8 与 #6。有点令人沮丧,但我完全同意这一点。
剩下的问题:
嗯,这肯定有一个错误。 (我昨天刚刚在 PoshCode Wiki 上写了一个关于它的页面,实际上,连接上有一个错误)。
先回答,后面有更多问题:
要从具有
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | <##>"$a" 1 2 3 <##> $OFS ="-" # Set the Output field separator <##>"$a" 1-2-3 <##>"{0}" -f $a 1 <##> $a.Length 3 <##>"{0}" -f $a 1-2-3 # You can enforce correct behavior by casting: <##> [PSObject]$b = 1,2,3 <##>"{0}" -f $a 1-2-3 |
请注意,当你这样做时,它们在传递给 -f 时不会展开,而是会正确输出——就像你将变量直接放在字符串中时那样。
为什么案例#3 没有遭受与#4 相同的命运? $rhs 应该保存嵌套数组 (,("a","a")) 但它的外层正在展开......某处......
答案的简单版本是 #3 和 #4 都在展开。不同的是,在4中,内部的内容是一个数组(即使在外部数组展开之后):
2 3 4 5 | $rhs[0].GetType() # String $rhs ="a","b" | SquareAndWrap $rhs[0].GetType() # Object[] |
#9-10 中的各种分组运算符是怎么回事?为什么他们的行为如此不规律,为什么需要他们?
正如我之前所说,数组应该算作格式的单个参数,并且应该使用 PowerShell 的字符串格式规则(即:用
当然,我们已经观察到其中有一个错误。
我没有看到任何异常,但是:就我所见,@() 和 $() 对于 9 和 10 的工作方式相同(实际上,主要区别是由 ForEach 展开的方式引起的顶级数组:
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | > $rhs | % { $lhs -f @($_);" hi" } a a hi b b hi > $rhs | % { $lhs -f $($_);" hi" } a a hi b b hi # Is the same as: > [String]::Format("{0} {1}", $rhs[0] );" hi" a a hi > [String]::Format("{0} {1}", $rhs[1] );" hi" b b hi |
所以你看到的错误是@() 或 $() 将导致数组作为 [object[]] 传递给字符串格式调用,而不是作为具有特殊 to-string 值的 PSObject。 为什么 #10 的失败不会像 #4 那样优雅地降级? 这基本上是相同的错误,但表现形式不同。数组不应该在 PowerShell 中以"System.Object[]"的形式出现,除非您手动调用它们的原生 如果您在传入数组的属性之前访问它,或者将它转换为 PSObject,就像我的原始示例中一样,您可以看到这一点。从技术上讲,#10 中的错误是正确的输出:您只将一个东西(一个数组)传递给 string.format,而它需要两个东西。如果您将 $lhs 更改为"{0}",您会看到使用 $OFS 格式化的数组 我想知道,考虑到我的第一个例子,你喜欢哪种行为,你认为哪种行为是正确的?我认为 $OFS 分隔的输出是正确的,而不是像 @(wrap) 它那样展开数组,或者将其转换为 [object[]] (顺便提一下,如果将它转换为 [int[ ]] 是一种不同的错误行为):
2
3
4
5
6
7
8
9
10
11
1
>"{0}, {1}" -f [object[]]$a # just to be clear...
1,2
> "{0}, {1}" -f [object[]]$a,"two" # to demonstrate inconsistency
System.Object[],two
>"{0}" -f [int[]]$a
System.Int32[]
我确信很多脚本是在不知不觉中利用这个错误编写的,但我仍然很清楚,在只是为了清楚的例子中发生的展开不是正确的行为,而是因为, 在对 .Net
我认为必须解决这个问题。如果想要保持展开数组的"功能",应该使用@splatting 操作符来完成,对吧?
Square 和 Wrap 都不会执行您在 # 的 5 和 7 中尝试的操作。无论您是像在 Square 中那样将数组放在分组表达式 () 中,还是像在 Square 中那样使用逗号运算符总结一下,当您在管道中使用这些函数时,它们的输出将展开,因为它一次一个地馈送到下一个管道阶段。类似地,在 6 和 8 中,管道中的多个对象并不重要,Square 和 Wrap 都会一次将它们送出到您的 foreach 阶段。
案例 9 和 10 似乎表明 PowerShell 中存在错误。拿这个修改后的片段试试看:
2 3 4 5 6 7 8 9 | # 9. only @() and $() succeed $_.GetType().FullName $_.Length $lhs -f [object[]]$_ $lhs -f [object[]]($_) $lhs -f @($_) $lhs -f $($_) } |
它有效。它还表明,foreach 已经接收到一个大小为 2 的 object[],因此
我"认为"你在 Wrap 中的目标是:
这将累积所有管道输入,然后将其作为单个数组输出。这适用于案例 8,但您仍然需要在
顺便说一句,Square 和 Wrap 中的括号以及 SquareAndWrap 中的外部括号都是不必要的。
我正在学习如何使用Nokogiri,根据这段代码我遇到了一些问题:require'rubygems'require'mechanize'post_agent=WWW::Mechanize.newpost_page=post_agent.get('http://www.vbulletin.org/forum/showthread.php?t=230708')puts"\nabsolutepathwithtbodygivesnil"putspost_page.parser.xpath('/html/body/div/div/div/div/div/table/tbody/tr/td/div
总的来说,我对ruby还比较陌生,我正在为我正在创建的对象编写一些rspec测试用例。许多测试用例都非常基础,我只是想确保正确填充和返回值。我想知道是否有办法使用循环结构来执行此操作。不必为我要测试的每个方法都设置一个assertEquals。例如:describeitem,"TestingtheItem"doit"willhaveanullvaluetostart"doitem=Item.new#HereIcoulddotheitem.name.shouldbe_nil#thenIcoulddoitem.category.shouldbe_nilendend但我想要一些方法来使用
关闭。这个问题是opinion-based.它目前不接受答案。想要改进这个问题?更新问题,以便editingthispost可以用事实和引用来回答它.关闭4年前。Improvethisquestion我想在固定时间创建一系列低音和高音调的哔哔声。例如:在150毫秒时发出高音调的蜂鸣声在151毫秒时发出低音调的蜂鸣声200毫秒时发出低音调的蜂鸣声250毫秒的高音调蜂鸣声有没有办法在Ruby或Python中做到这一点?我真的不在乎输出编码是什么(.wav、.mp3、.ogg等等),但我确实想创建一个输出文件。
我在从html页面生成PDF时遇到问题。我正在使用PDFkit。在安装它的过程中,我注意到我需要wkhtmltopdf。所以我也安装了它。我做了PDFkit的文档所说的一切......现在我在尝试加载PDF时遇到了这个错误。这里是错误:commandfailed:"/usr/local/bin/wkhtmltopdf""--margin-right""0.75in""--page-size""Letter""--margin-top""0.75in""--margin-bottom""0.75in""--encoding""UTF-8""--margin-left""0.75in""-
给定这段代码defcreate@upgrades=User.update_all(["role=?","upgraded"],:id=>params[:upgrade])redirect_toadmin_upgrades_path,:notice=>"Successfullyupgradeduser."end我如何在该操作中实际验证它们是否已保存或未重定向到适当的页面和消息? 最佳答案 在Rails3中,update_all不返回任何有意义的信息,除了已更新的记录数(这可能取决于您的DBMS是否返回该信息)。http://ar.ru
我在我的项目目录中完成了compasscreate.和compassinitrails。几个问题:我已将我的.sass文件放在public/stylesheets中。这是放置它们的正确位置吗?当我运行compasswatch时,它不会自动编译这些.sass文件。我必须手动指定文件:compasswatchpublic/stylesheets/myfile.sass等。如何让它自动运行?文件ie.css、print.css和screen.css已放在stylesheets/compiled。如何在编译后不让它们重新出现的情况下删除它们?我自己编译的.sass文件编译成compiled/t
我有多个ActiveRecord子类Item的实例数组,我需要根据最早的事件循环打印。在这种情况下,我需要打印付款和维护日期,如下所示:ItemAmaintenancerequiredin5daysItemBpaymentrequiredin6daysItemApaymentrequiredin7daysItemBmaintenancerequiredin8days我目前有两个查询,用于查找maintenance和payment项目(非排他性查询),并输出如下内容:paymentrequiredin...maintenancerequiredin...有什么方法可以改善上述(丑陋的)代
我正在寻找执行以下操作的正确语法(在Perl、Shell或Ruby中):#variabletoaccessthedatalinesappendedasafileEND_OF_SCRIPT_MARKERrawdatastartshereanditcontinues. 最佳答案 Perl用__DATA__做这个:#!/usr/bin/perlusestrict;usewarnings;while(){print;}__DATA__Texttoprintgoeshere 关于ruby-如何将脚
我的代码目前看起来像这样numbers=[1,2,3,4,5]defpop_threepop=[]3.times{pop有没有办法在一行中完成pop_three方法中的内容?我基本上想做类似numbers.slice(0,3)的事情,但要删除切片中的数组项。嗯...嗯,我想我刚刚意识到我可以试试slice! 最佳答案 是numbers.pop(3)或者numbers.shift(3)如果你想要另一边。 关于ruby-多次弹出/移动ruby数组,我们在StackOverflow上找到一
Rackup通过Rack的默认处理程序成功运行任何Rack应用程序。例如:classRackAppdefcall(environment)['200',{'Content-Type'=>'text/html'},["Helloworld"]]endendrunRackApp.new但是当最后一行更改为使用Rack的内置CGI处理程序时,rackup给出“NoMethodErrorat/undefinedmethod`call'fornil:NilClass”:Rack::Handler::CGI.runRackApp.newRack的其他内置处理程序也提出了同样的反对意见。例如Rack