How to care for your Invisalign braces
I wore Invisalign braces from January of 2022 to early 2023. They require a lot of brushing and maintenance while wearing them. Here’s a few things I did along the way which made that easier. 1. Create brushing stations You’re going to brush and floss a lot. (Like a lot.) Anytime you eat or drink anything besides water you must remove the Invisalign trays, brush your teeth and trays, and then floss....
Using git worktrees
Have you ever been developing on a feature branch and needed to look at a separate branch on the same repo? I have. When this happens, I normally do one of two things: git stash my changes and change branches This is annoying because it’s a lot of steps. I also have to remember which stash to pop when I come back to this branch. Stage all my changes and store them in a work-in-progress commit This is better than #1 but doesn’t let you view both branches simultaneously....
How my digital life is backed up
Derek Sivers recently wrote a post explaining how he backups his computers. His post inspired me to improve my own backup strategy and also to write this post. My computer I only have two personal computers whose data I care about; my Macbook Pro and my wife’s Macbook Air. The strategies for backing these up are the same, so I’ll just talk about my computer. It has a lot of important things: files, videos, photos, personal code, and more....
Running a subset of Go tests
It is often useful to run a subset of the tests in a Go project. You might do this because you only want to see test results for one package or to run tests faster. For these examples, assume your project is a Go module named examplemodule. It has the following structure: examplemodule |_ go.mod |_ go.sum |_ internal |_ foo | |_ foo.go | |_ foo_test.go |_ bar |_ bar....
Max and min integer values in Golang
Today I needed to use the maximum unsigned 64-bit integer value possible in Golang. Here is a short program I wrote with some help from Stack Overflow to help me remember how to calculate these without any dependencies. package main import "fmt" const ( minUint32 = uint32(0) maxUint32 = ^uint32(0) minUint64 = uint64(0) maxUint64 = ^uint64(0) minInt32 = int32(-maxInt32 - 1) maxInt32 = int32(maxUint32 >> 1) minInt64 = int64(-maxInt64 - 1) maxInt64 = int64(maxUint64 >> 1) ) func details[numeric int32 | int64 | uint32 | uint64](name string, num numeric) { fmt....
Using 'git commit --fixup'
I learned something new from Julia Evans today. Git has a --fixup argument when committing files which makes it easy to create fixup commits which can get automatically squashed when rebasing. This is fantastic! I’ve known about git commit --amend for years, but this allows you to fixup commits which are several commits back without manually moving a bunch of lines around while interactively rebasing… Let’s assume you have a repo which looks like shown below....
Go build tags
Today I learned about Go build tags. Here’s some quick notes to help me remember how to use them. Assume you have directory like so: $ ls -1 extra.go go.mod main.go And main.go has contents: package main import "fmt" var numbers = []string{ "one", "two", } func main() { for _, number := range numbers { fmt.Println(number) } } And extra.go has contents: //go:build extrastuff package main func init() { numbers = append(numbers, "three", "four") } If you build without any tags, you get this:...
Using gonew to easily create template repos
Now that I’ve been writing Golang for a while, when I start a new project, I typically know the sort of layout I’m looking for. I typically go for something like this: . ├── cmd │ └── demo │ └── main.go ├── go.mod ├── internal │ └── subpkg │ ├── subpkg.go │ └── subpkg_test.go └── LICENSE And often there are lots of ascillary files that go along with this, like Makefiles, CI/CD config files, Dockerfiles, docker-compose files, etc....
Checking an error's type in Golang
I was not very familiar with checking an error’s type in Golang, so I spent a few minutes learning about it today. It turns out that it’s incredibly easy to do. Running the below code shows the output: 2009/11/10 23:00:00 got custom error: err1 package main import ( "errors" "log" ) var ( customErr = errors.New("err1") // create a error, identified by its var name ) // oops always returns our custom error....
Benchmarking Unnecessary Allocations
I’ve also been thinking more about unnecessary allocations in my Go code and how to avoid them by pre-declaring the length of a slice up front. Normally, I’d write something like this: var s []int for _, val := otherSlice { s = append(s, val) } Since I don’t specify the size of s, if otherSlice is large, the array underlying s might not be large enough to hold all the values; then a new array will have to be allocated and (I presume) all existing values copied out of it one at a time to fill the new array....