Hacker News new | ask | show | jobs
by knicknic 1982 days ago
I like powershell, but miss

bash set -e.(really really miss this)

Find it hard to set a script to abort with a stack trace.

Find it hard to deal with relative imports(this script imports a file in the same folder)

explaining the scoping rules

Disklike explains how your array is now a single object when you returned it from a function

Absolutely love powershell JSON support, miss native yaml support.

Love parameter globing

Love integration of parameters with a script, dislike that auto generated help can’t be done via single line comment to function

1 comments

> bash set -e.(really really miss this)

    Set-PSBreakpoint -Command Write-Error -Action { break; }
similarly:

    trap { <# IDE breakpoint here #> }
> Find it hard to set a script to abort with a stack trace.

    $script:ErrorActionPreference = 'Stop'
    # or
    throw "Oops!"
> Find it hard to deal with relative imports

That's a very unfortunate limitation that I've never understood myself, to be honest. The typical "best practice" is to not use relative imports, but to use "installed" modules or scripts instead.

> explaining the scoping rules

https://docs.microsoft.com/en-us/powershell/module/microsoft...

> Disklike explains how your array is now a single object when you returned it from a function

This is also "one of those irritations" that tends to bite people when dealing with search results, e.g.: "Get-ADUser". If you always want an array (even an empty or single-valued array) then wrap functions in @(...), e.g.:

    $users = @( Get-ADUser -Filter ... )
This is also the syntax to create an empty array, or an array of one item:

    $empty = @()
    $listOfOne = @( 'foo' )
> miss native yaml support

But this would be trivial to add. Writing a module to provide commandlets such as "ConvertFrom-Yaml" and "ConvertTo-Yaml" is about a day of effort in PowerShell. Good luck doing the same thing in Bash and producing something useful, let alone full-featured!

In fact, someone has done it:

https://github.com/cloudbase/powershell-yaml

> auto generated help can’t be done via single line comment to function

Two lines for automatically generated help is one too many?

    # .SYNOPSIS
    # This works...
    echo 'foo'
`bash set -e`. Your examples don't work (if you have an answer please paste it in https://github.com/PowerShell/PowerShell/issues/3415 )

    Set-PSBreakpoint -Command Write-Error -Action { break; }
    cmd.exe /c "exit 1"
    echo "if this->($LASTEXITCODE) is 1 I shouldn't be here"
Your stack trace code is wrong. What your code is doing is essentially saying throw an exception when you encounter an error. All I am asking is when exception hits the top, dump the stack trace.

    $script:ErrorActionPreference = 'Stop'
    function bar() {
        throw "oops"
    }
    function foo() {
        $a = 123
        bar
    }

    foo

    PS C:\tmp> .\a.ps1

    Exception: C:\tmp\a.ps1:6:5
    Line |
    6 |      throw "oops"
        |      ~~~~~~~~~~~~
        | oops
I use `trap{$_.ScriptStackTrace; break}` but unfortunately I cannot hide this code into a helper script that I can dot source... because of scoping rules! Even though I am dot sourcing a file which I would think would load it into my current scope according to dot sourcing link you sent.

Why this is not the default behavior when leaking an exception and aborting I have no clue

enforcing things are arrays

    yes you can wrap stuff in arrays, but that is making the callsite look ugly for a function definition problem. The solution "return ,$array" is just weird

Honestly I prefer the bash way of $yaml | yaml2json(.exe) | convert-fromjson. Easier to find cross platform converters which your example is not. Takes me like 5 seconds to write, however then I have to teach others to do it as well, I want it in the platform. Also why they are at it, add toml support as well.

for documentation

  # .SYNOPSIS
  # Why do I need to type .SYNOPSIS above here, and yes that extra line is too many
  function foo(
      # but here its just obviously a comment for a parameter
      [string] $param=""
  ) {
      $param
  }
Also didn't mention this before I wish there was a version of powershell that was static checked like typescript for javascript.
> Honestly I prefer the bash way of $yaml | yaml2json(.exe) | convert-fromjson

I always prefer native support, but that's just me. I recently even wrote a converter for DNS bind zone files because they're such a pain to deal with as "text" files.

> Why do I need to type .SYNOPSIS above here, and yes that extra line is too many

Because there are other sections as well.

Consider yourself lucky! If you're writing binary modules in C#, the automatic help generation is missing. Instead, you have to use a hideous legacy XML-based help system nobody asked for. There are thankfully generators available now that plug into the Visual Studio build system, but in the past you literally had to author these by hand.

> I wish there was a version of powershell that was static checked like typescript for javascript.

Don't we all?

Set-StrictMode adds some static checks (not enough IMHO), and there are also linters available. If using VS Code, you get a bunch by default.

Fundamentally, once I start getting too frustrated by the weak typing, I realise that I'm writing software, not scripts. I simply crack open Visual Studio and start writing C#...

> Why this is not the default behavior

PowerShell conceptually is nearly perfect at a high level. It was originally called the "monad shell", and that design pedigree still shines through.

Unfortunately the implementation has many gaps that are as yet unresolved.

I was hoping PowerShell Core would fix everything, but it only fixed a few things (parallel foreach finally!) while leaving simple things like break-on-exception on the table.

Nonetheless, having worked with both Bash and PowerShell, I hugely prefer the latter because of that purity of vision.