The easier, less invasive but also less accurate option would be to publish an empty crate with a random name that does not exploit typos (just some random junk) and check how often that crate is downloaded.
You can assume that almost all downloads for this crate are bot downloads and just subtract that amount from the downloads of the typo-squatted crate
AFAIK antivirus systems do (did?) not scan RAM, only persistent memory. So decrypting/decoding the malware in-memory and jumping into the code should avoid detection. That's how "runtime crypters" work or used to work a few years ago.
I use nixpkgs on my osx laptop for most everything over homebrew these days, I've upgraded nix to 2.4, but home-manager isn't compatible. Hopefully that will change soon.
Good thing about nix package manager is that you can have same path using it on macOS and on Linux, so your shell config files are easier to maintain without if's.
Linuxbrew installing at /home/linuxbrew/.linuxbrew/ is a bit of a joke too.
> Most of the tests I write aren't for pure functions
In response to this, I recommend the "Functional Core, Imperative Shell"[0] talk/pattern. The idea is to extract your business logic as pure functions independent of the data access layer. This pattern allowed me to test large portions of a code base using property tests. This works really well in most cases and gives me much more confidence in the product that will be deployed.
While the pattern is good to always be striving for, I think it can be too much boilerplate at times.
If I've got say 100 lines of business logic, it makes sense to have 10 lines to do the necessary data shuffling to get everything in order so that you can keep your business logic a nice pure function.
On the other hand, if you have 5 lines of business logic, it maybe doesn't make sense to have 10 lines of shuffling data to be able to keep the business logic a pure function. Not so much for the time to write it but because it can obscure the functionality for the reader.
During the quarantine, I started photographing on film, developing the film at home and digitize the negatives using my DSLR. At least for B/W film, the process of developing film yourself is dead easy and I'm happy to have a hobby away from my computer. Also, having a price per picture and only a limited amount of shots helps me actually think about composing nice pictures instead of taking 5 almost identical images and moving on.
In general, film photography is having a comeback. Prices for used film cameras skyrocketed in the last years for a few models.
Personally, I find photographing on film really rewarding. Having a physical product in the end (be it a print of the image or only the negatives) makes the process more enjoyable. So if you have some old film cameras lying around, I can only recommend giving them a try. Maybe there are even old films with old memories in these cameras.
When validation gets complex (e.g. there are many criteria to check), I like to build a list/stream/array (what ever the language offers) of tuples of predicates (functions from the object that gets validated to boolean) and strings (or functions from the object to string so I can have context in my error messages).
Then iterate over the tuples, if a predicate fails, return the associated error message and throw an error/display the message to the user.
In the end it looks something like this:
var validators = Stream.of(
Map.entry(user -> user != null, "User must be defined"),
Map.entry(user -> user.firstName != null, "Missing first name"))
validators.filter(e -> e.getKey().apply(userToBeValidated)).map(Map.Entry::getValue).getFirst()
(This example uses Map.entry for tuples as Java lacks native support for tuples)
This limits branching and you have all validation criteria neatly organized in the same location.
Sure, if you're validating some data there're loads of better ways to do it than a bunch of conditionals. I was purely commenting on the switch(true) pattern vs some "if"s.
That approach looks nice though. On that subject, JS has some nice libraries including io-ts[1] which has a functional approach using Eithers to encapsulate errors/success.
Agreed, +1
This pattern goes beyond JS and is very helpful for supporting tests; you've already factored out your validators. There's always going to be stragglers but you can define and push in an extra check on the spot (i.e. using lambda funcs at least in JS).
In perl you would want to use `or` instead of `||` to take advantage of the low precedence, so you can type things like `dostuff $foo or die` which is logically 'do stuff, and if it fails, die' as opposed to 'die if $foo is false', which you'd get with ||
You can install nix side by side to your distro package manager and only install some packages using nix. You could also use something like lorri and direnv and let nix only manage your code projects and when entering the project directory, drop you into a shell with only the dependencies you need for this specific project installed.