Suppress Array List Add method pipeline output
Asked Answered
P

2

5

I am using an Array List to build a sequence of log items to later log. Works a treat, but the Add method emits the current index to the pipeline. I can address this by sending it to $null, like this

$strings.Add('junk') > $null

but I wonder if there is some mechanism to globally change the behavior of the Add method. Right now I have literally hundreds of > $null repetitions, which is just ugly. Especially when I forget one.

I really would like to see some sort of global variable that suppresses all automatic pipelining. When writing a large script I want to intentionally send to the pipeline, as unexpected automatic send to pipeline is a VERY large fraction of my total bugs, and the hardest to find.

Payton answered 10/7, 2019 at 7:37 Comment(6)
You can suppress the output from appearing in the console (see here), but it would still be captured or returned by functions. AFAIK there's no general option that would suppress the output of the Add() method. Why are you using an ArrayList collection in the first place? Do you need a particular feature that regular PowerShell arrays don't provide?Sweeper
@Ansgar, yes, I am constantly adding an arbitrary number of new log line items, and += is not very efficient in that situation. Ending every Add with > $null isn't the end of the world, so I'll keep doing that. And keep dreaming of a global pipeline suppression option for scripting, so I can choose what goes to the pipeline, rather than needing to suppress a ton of stuff I don't want in the pipeline.Payton
I am curious, when would anyone actually need to get the element count at every add, vs just discretely getting the Count? I don't understand the use case for this "feature", which is part of why it annoys me so. :)Payton
Curious why nobody recommended to use Collections.Generic.List<T> as answer to this question... it's been there since .NET 2.0 iircHalm
Hadn't looked at this thread in ages, but in the end that is EXACTLY what I did.Payton
Hahha well you should self-answer and give your question closure no?Halm
P
6

So, this thread getting resurrected has led me to "answer" my own question, since I discovered long ago that ArrayLists have been deprecated and Collections.Generic.List<T> is the preferred solution, as pointed out by @santiago-squarzon today.

So, for anyone wondering

$log = [System.Collections.Generic.List[String]]::new()

or the older New-Object way

$log = New-Object System.Collections.Generic.List[String]

to instantiate the collection, then happily

$log.Add('Message')

with no pipeline pollution to worry about. You can also add multiple items at once with

$log.AddRange()

With the range being another list, or an array if you cast to List first. And you can insert a message with something like

$log.Insert(0, 'Message')

So yeah, lots of flexibility and no pollution. Winning.

Payton answered 15/11, 2022 at 20:26 Comment(1)
However this adds pollution for .Remove(), [System.Collections.Generic.List[String]] outputs "True" if successfully removed. While [System.Collections.ArrayList] outputs the index only for .Add(). So it's a stalemate, and we still haven't found a solution that works for all operations.Skilled
S
4

You could wrap your ArrayList in a custom object with a custom Add() method.

$log = New-Object -Type PSObject -Property @{
    Log = New-Object Collections.ArrayList
}
$log | Add-Member -Type ScriptMethod -Name Add -Value {
    Param(
      [Parameter(Mandatory=$true)]
      [string]$Message
    )

    $this.Log.Add($Message) | Out-Null
}

$log.Log.Add('some message')  # output on this is suppressed
Sweeper answered 10/7, 2019 at 22:41 Comment(2)
out-null works but the overhead of pipes could be significant in large loopsBrehm
Pipes became the bane of my existence towards the end of my PowerShell based life. I wanted nothing more than to have a flag that just turned them off, since they got polluted all the time, and massive performance problems, and are a real PITA to debug. Instead I dumped PowerShell, sold my old product and my new venture will be 100% Swift. I won't miss PowerShell.Payton

© 2022 - 2024 — McMap. All rights reserved.