The Author Online Book Forums are Moving

The Author Online Book Forums will soon redirect to Manning's liveBook and liveVideo. All book forum content will migrate to liveBook's discussion forum and all video forum content will migrate to liveVideo. Log in to liveBook or liveVideo with your Manning credentials to join the discussion!

Thank you for your engagement in the AoF over the years! We look forward to offering you a more enhanced forum experience.

JeffB (3) [Avatar] Offline
#1
The example on p. 301

$words | % {$h=@{}} {$h[$_] += 1}

is just fine, but I wouldn't think so if I read the text of 'get-help foreach-object -full', which tells me that the process scriptblock is the *only* positional parameter, and that it's in position 1. According to the help file, the begin clause isn't positional, so the code above shouldn't work.

Is there an error in the help file, or am I badly misunderstanding the idea of positional parameters?
brucepay (155) [Avatar] Offline
#2
Re: p. 301 and PS documentation of foreach-object
The helpfile is actually correct (in fact the signatures are extracted from the code) however the way it works is the tricky bit.

If you look at the signature of the -Process parameter, you'll see that, yes, it is positional but it also takes a collection of scriptblocks and receives all remaining unbound arguments. So, in the case of

dir | foreach {$sum=0} {$sum++} {$sum}

The Process parameter is getting an array of three scriptblocks whereas Begin and End are empty. Now here's the trick. If Begin is empty and Process has more than two scriptblocks in the collection, then the first one is treated as the Begin scriptblock and the second one is treated as the Process scriptblock. If Begin is specified, but End is not and there are two scriptblocks, then the first one is treated as the Process clause and the second one is the End clause. Finally, if both Begin and End are specified then the remaining arguments will be treated as multiple Process clauses. This allows

dir | foreach {$sum=0} {$sum++} {$sum}
dir | foreach -begin {$sum=0} {$sum++} {$sum}
dir | foreach {$sum=0} {$sum++} -end {$sum}
dir | foreach -begin {$sum=0} {$sum++} -end {$sum}
and
dir | foreach -begin {$sum=0} -process {$sum++} -end {$sum}

to all work as expected. As I recall, I had a conversation with the technical writer at the time, trying to explain all of this and the consensus was that we were probably better off *not* trying to document the details since it required a complicated solution to achieve a simple experience. Still - I'll forward this to the writer and see what she thinks.

Thanks,
-bruce