1/ `?` is an alias for Where-Object and `%` is an alias for ForEach. So you can do `obj | ? filter | % block` to do things compactly.
`&` lets you invoke a string or script-block as a powershell command
2/ ctrl-space gives you a menu-completion for all options. This means you can write `obj.` and hit ctrl-space to get all its properties.
Alternatively, you can pipe the object to the `get-member` cmdlet
3/ You can really easily define your own tab-completion options with `Register-ArgumentCompleter`. It takes a script block, meaning you can do fun dymanic completions, AND ALSO you can use it on both builtin and user-defined commands!
4/ Powershell has "providers" which give you access to various windows objects like they were files. Want to find every environmental value that starts with `Local`? Easy, just do
5/ Functions can have `begin`, `process`, and `end` subsections. When piped into, `begin` is run once, `process` on every item, and `end` afterwards. `Foreach` supports this, too:
BTW, I don't really count this as a "powershell trick", but windows supports forward-slash paths too. You can write `C:/foo/bar` and it'll work just fine
6/
```
function Do-Thing([switch]$x) {
# ...
}
> Do-Thing # $ x is false in function body
> Do-Thing -x # $ x is true in function body
```
7/ You can create a detacted powershell session on your computer with
You can also do `invoke-command -ScriptBlock {script} -InDisconnectedSession -ComputerName localhost -EnableNetworkAccess`
Unfortunately tho only one terminal can receive from a remote local session at a time which defeats my use case /sad
8/ Want inline completion prompts? Here ya go:
```
Install-Module -Name PSReadLine -AllowClobber -Force
Set-PSReadLineOption -PredictionSource History
```
9/ You can go back and forth in your location history with `cd -` and `cd +`. There's also a weird "multiple location stacks" feature I haven't played with yet
10/ Select-Object can take blocks to get custom properties. You can pass in blocks stored in variables:
11/ In addition to being able to start background processes with `command &`, you can use `Start-Job` to give names to jobs for easy receiving later. You can also assign jobs (and remote sessions) to variables!
12/ ctrl-space works on flags, too. You can write `gci -` and press ctrl-space to get all the possible parameters to `get-childitem`
13/ Sort-Object can take an array of blocks/properties, in which case it'll sort in that order
In retrospect I don't like that tip very much, so here's a better one:
13/ You reload your profile with `. $PROFILE`
• • •
Missing some Tweet in this thread? You can try to
force a refresh
More tech things need a "conceptual overview", which explains the why and core ideas to an outsider who wants to know what it's all about, but isn't necessarily interested in deeply understanding it.
Lemme try doing this with vim:
1. When editing text, shortcuts are really useful. There's only so many buttons on a keyboard, though. To get more shortcuts, vim has two "editing modes". One mode behaves like any other text editor. In the other mode, all the letter keys become commands, like "next sentence".
2. While you can use the mouse, vim is keyboard-centric. There are some historical reasons for this but the main advantage is that you can more easily build muscle memory for using commands and then do lots of edits without needing to think about what you're actually pressing.
I am endlessly fascinated with content tagging systems. They're ubiquitous in software and have so many nuances, but I can't find anything on how to design and implement anymore more than the barebones basics of a system.
Some thoughts in a thread.
A tag is a metadata label associated with content, primarily used for querying and grouping. The tag name is also the id: two tags with the same name are the same tag.
Tags appear everywhere: #hashtags, wikipedia categories, blog post labels, AWS infra tags...
Now, are `horse` and `horses` the same tag? They're different strings, but I'd be pretty miffed if I queried for `horse` and got only half the data.
So for serious querying we need some kind of relationship between tags
An adult human male can feed 100 people a luxurious 1200 Calorie meal. Mickie Mouse's head:body ratio suggests he's nowhere near done growing. He'd probably taste like veal
(disclosure: the linked image is probably a hoax, since Disney has a minimum food charge per person. I checked and confirmed it's in addition to the minimum event charge, so they couldn't have swapped food for other event services)
Pleased to announce a new #NFT offering: #eNdFT! We are minting one cause of death NFT for every person on earth, which is 100% guaranteed to reflect the way you do, in fact, actually die.
Unless you trade it! Unhappy with your "car crash" #eNdFT? Exchange it for an "old age"!
Of course, you better be prepared to pay through the nose for "old age". Due to the nature of our product, eNdFTs cannot be bought or sold, only be traded 1-1 for another #eNdFT (plus an optional eth price to cover value differences). There is no escaping death.
Please note that our prediction software isn't perfect. While every #eNdFT is accurate, they may be imprecise. For example, you could receive "Most likely drowning" NFT, or "either cancer or stabbing". We expect this uncertainty will affect each #eNdFT's market value.
I read @laurencetratt's piece "Multiplicty Choices are Hard to Model and Change" and it got me thinking about the relationship between ergonomics and software correctness. His claim is it's easy to model 0, 0-1, or 0-∞ of something, but not 1-2 or 1-∞
For one or more T's, you could write `[T]`. But [] ∈ [T], so you can have 0 T's!
Now the common counter is that you can model "one or more" as the tuple (T, [T]), which is sorta what the Haskell `Nonempty` type does hackage.haskell.org/package/base-4…
But now you have a problem because (T, [T]) isn't actually a subtype of [T], meaning you have to reimplement all of the list operations for (T, [T]). That's the bad ergonomics, and you can have bugs reimplementing them, though arguably fewer than bugs from using too big a type