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.

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? Commented Jul 10, 2019 at 10:53
  • @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. Commented Jul 10, 2019 at 14:37
  • 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. :) Commented Jul 10, 2019 at 14:39
  • 1
    Curious why nobody recommended to use Collections.Generic.List<T> as answer to this question... it's been there since .NET 2.0 iirc Commented Nov 15, 2022 at 17:28
  • 1
    Hahha well you should self-answer and give your question closure no? Commented Nov 15, 2022 at 17:51

2 Answers 2

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.

Sign up to request clarification or add additional context in comments.

1 Comment

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.
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

2 Comments

out-null works but the overhead of pipes could be significant in large loops
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.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.