The Wiert Corner – irregular stream of stuff

Jeroen W. Pluimers on .NET, C#, Delphi, databases, and personal interests

  • My badges

  • Twitter Updates

  • My Flickr Stream

  • Pages

  • All categories

  • Enter your email address to subscribe to this blog and receive notifications of new posts by email.

    Join 2,317 other followers

Archive for February 18th, 2021

PowerShell: avoid Write-Output, use Return only for ending execution, use $Output variable for returning additional output

Posted by jpluimers on 2021/02/18

Recently, I bumped into [WayBack] Write-Output confusion for the upteenth time.

Luckily I had the below links archived, basically invalidating the use of Write-Output, and invalidating the answer at [WayBack] powershell – What’s the difference between “Write-Host”, “Write-Output”, or “[console]::WriteLine”? – Stack Overflow.

  • [WayBack] Write-Output vs. Return vs. $Output · Issue #46 · PoshCode/PowerShellPracticeAndStyle · GitHub
    @maekee to sum up this long thread:

    In other programming languages with a return statement, the return statement is contractual: nothing returns output from a function except the return statement. Thus, for people with experience in other languages, the presence of code like return $output in PowerShell is misleading. They think: “oh, ok, PowerShell has a return statement” and don’t realize that any un-captured result values get output also — and don’t even realize they can output multiple times.

    The reasoning for, and objection to, Write-Output is similar. People like it because:

    … always explicitly sending an object to a stream… makes it easier to understand [the code] at a glance in the future.

    The problem is that this can lead to a false sense of security. If you see Write-Output you assume that output can only come from lines with Write-Output, when in reality it can come from any command or method call. Or at least, any that doesn’t start with an assignment (or [void] cast), or end with out-null …

    So while some people like it because it highlights the spots where you intentionally output something — other people argue it’s presence distracts you from the fact that other lines could output.

    Therefore

    Since return cannot always be used (sometimes you need to write output more than once), you should prefer Write-Output and use return only for ending execution. But since Write-Output can lead to false expectations and in addition is slightly slower, (and worse, can be overwritten by functions or aliases) …

    We recommend:

    Use return only for ending execution.

    Avoid Write-Output (although you may want to use for it’s -NoEnumerate switch). Instead, when you want to make output clearer, just assign output to a relevantly named variable. and put that a variable on a line by itself to signal explicit output.

  • and

    Jaykulcommented 12 hours ago

    TIL Write-Output -NoEnumerate is broken on PowerShell 6 and has been for 16 months or longer — there’s no plan to fix it. In summary:

    DO NOT USE Write-Output — EVER.

  • [WayBack] Write-Output -NoEnumerate outputs PSObject[] rather than Object[] and generally doesn’t respect the input collection type · Issue #5955 · PowerShell/PowerShell · GitHub

Via:

[WayBack] Joel Bennett on Twitter: “

Write-Output considered EVEN MORE harmful! Most #PowerShell experts recommend against Write-Output

Now, I find there is a long standing bug in PowerShell 6’s -NoEnumerate switch. 

I no longer accept PRs which use Write-Output”

–jeroen

Posted in CommandLine, Development, PowerShell, PowerShell, Scripting, Software Development | Leave a Comment »

showthedocs

Posted by jpluimers on 2021/02/18

[WayBack] showthedocs

is a documentation browser that finds the relevant docs for your code. It works by parsing the code and connecting parts of it to their explanation in the docs

, and supports these languages:

  • SQL
    • postgresql
    • mysql
  • Configuration
    • nginx
    • gitconfig

You can enter any language text, then click the language, followed by clicking the “SHOW ME THE DOCS!” button, for which an example is further below.

The site has an open architecture, allowing to plug in more languages and documentation:

 

gitconfig example

So for instance the below ./git/config file leads to this result [WayBack] where you can click on all the coloured areas for easy navigation through the documentation:

Read the rest of this entry »

Posted in *nix, *nix-tools, Database Development, Development, DVCS - Distributed Version Control, git, MySQL, nginx, PostgreSQL, Power User, Software Development | Leave a Comment »

Delphi: not all lists need to be generic

Posted by jpluimers on 2021/02/18

Lots of Delphi programmers made, or are making the move, of classic Delphi based containers like TObjectList into generic containers like TList<T>.

A while ago, I got into a project that needed to extend lifetime of some objects. Virtually all of them were interface based, and most of the code was from the non-Unicode era, and most of the developers there had a strong background in that era, so they started fiddling with TList, found it hard, then thought “maybe TList<IInterface>” where will help.

The problem however, is that Delphi has no IList<T>. For that, you have to go to the Spring4D library.

Then I sat down with them, and proposed to use an instance good old TInterfacedList of which the context was maintained in an IInterfacedList field.

Back in the days where Delphi did not support non-generic types, TInterfacedList was the only built-in way to store interface references, and the Collection Classes framework by Ray Lischner were the only ways to do that in a more structured way (as they were based on interfaces, an idiom that Embarcadero should have used for their generic collections as well; Spring4D did, so use those collection classes and interfaces whenever possible as they are way more versatile than the Delphi built-in ones)

Back to using TInferfacedList, as it can still be useful today in:

unit InterfacesHolderUnit;

interface

uses
  DebuggableInterfacedObjectUnit, System.Classes;

type
  IInterfacesHolder = interface
    procedure Add(const aReference: IInterface);
  end;

  TInterfacesHolder = class(TInterfacedObject, IInterfacesHolder)
  strict private
    FInterfaces: IInterfaceList;
  public
    constructor Create();
    procedure Add(const aReference: IInterface);
  end;

implementation

{ TInterfacesHolder }

procedure TInterfacesHolder.Add(const aReference: IInterface);
begin
   FInterfaces.Add(aReference);
end;

constructor TInterfacesHolder.Create();
begin
   inherited Create();
   FInterfaces := TInterfaceList.Create();
end;

end.

and some tests:

Read the rest of this entry »

Posted in Conference Topics, Conferences, Delphi, Development, Event, Software Development | 1 Comment »

 
%d bloggers like this: