Generics in Go 1.18

In Go 1.18, we get access to Genrics. Huzzah! Here’s an basic example of how to use them: package main import ( "fmt" ) func PrintAge[age float32 | int64](myAge age) { fmt.Printf("age: %s \t type: %T\n", myAge, myAge) } func main() { var age1 float32 = 30.5 var age2 int64 = 32 PrintAge(age1) PrintAge(age2) } Running the above program gives us the below output. You can see that it happily accepted the float32 and int64 values without issue. age: %!s(float32=30.5) type: float32 age: %!s(int64=32) type: int64 This saves us from having to either (a) define a separate PrintAge function for every type of number we want to accept or (b) writing the PrintAge to accept type interface{} which would then accept types we don’t want to accept (and having to mess with type assertions and all that). ...

2022-07-12

Go defer

defer in go is used to run a function later on. Specifically, the specified function will run when the enclosing function returns. There’s no clean equivalent to this in Python that I’ve found. The quintessential example is closing a file handle as your program exits. Example package main import ( "fmt" "os" ) func main() { file := createFile("/tmp/testingdefer.txt") defer closeFile(file) writeFile(file) } func createFile(path string) (file *os.File) { fmt.Println("creating file: ", path) file, _ = os.Create(path) // skipping error handling for brevity return } func writeFile(file *os.File) { fmt.Println("writing file") fmt.Fprintln(file, "here is some data for you!") } func closeFile(file *os.File) { fmt.Println("closing file") file.Close() // skipping error handling for brevity }

2021-07-20

Empty Go Interfaces

When declaring function parameters in Go, you must type the incoming data. Here’s an example: package main import "fmt" func print_stuff(s string) { fmt.Println(s) } func main() { print_stuff("Passing string!") } s string indicates that we’re passing a variable of type string into the function. This prevents us from from passing into variables of any other type. For example, this will fail with ./prog.go:10:17: cannot use 42 (type untyped int) as type string in argument to example_str if you try to pass an integer. ...

2021-07-11

Line beaks in file names on Linux

Today I accidentally created a file whose name had a newline character in it. I didn’t notice it when I did it, but here’s how it showed up in my shell. There was a directory whose name shared the first few characters of the filename. [22:07] james_simas@widget /var/tmp $ ls o* oops? <--- Suspicious file! oops: <--- Directory I tried to delete it: [22:07] james_simas@widget /var/tmp $ rm 'oops?' rm: oops?: No such file or directory Then I realized the my shell wasn’t interpreting the character right: ...

2021-02-02

Translating characters with tr

I recently was having to work with Ansible for several days to deploy changes globally across prod. I was storing my playbook limit in a file like so: [18:45] james_simas@widget ~/Downloads $ cat limit.txt host1.domain.com host2.domain.com host3.domain.com At one point, I needed to use supply the list of hostnames in BASH, but rather than having them be newline separated, I needed them to be separated by commas like this: host1.domain.com,host2.domain.com,host3.domain.com I didn’t want to modify my original files (I still needed them) and this seemed like a problem somebody else has problably solved. I Googled a bit and found an answer using tr. ...

2021-01-14

How to use extra_vars_path in the tower_job_template Ansible module

Today I was using Ansible’s tower_job_template module in a playbook. I needed to add extra variables to the job template, but Ansible’s public documentation of the the tower_job_template module had no examples of how to do this. I was unable to find any compelling examples on Google. I was a bit of poking around the Ansible API, it turns out this was far easier than I had anticipated. Without further ado, here’s how you use extra_vars_path: ...

2020-03-19

Converting blog to Terraform & Ansible

Setting up my blog has always been easy. Previous to today, you just had to: Provision an Ubuntu 18 VM somewhere (I’ve been using Digital Ocean) Install Apache and remove its default website Use Hugo to generate the site’s static files and copy them to the VM host Done! But, never being one to sit still, I’ve decided to up my game and move to automatic provisioning with Terraform and Ansible. Why? Because it’s fucking cool, that’s why! ...

2019-10-05

Operating on a subset of lines with sed

Today a coworker posed an interesting question to me. Given a BIG-IP configuration file with thousands of records like this… gtm pool /Common/p_example { members { /Common/2001:668:fc78:0:f811:3ef2:fed7:98cc:vs6_2001_668_fc78_0_f811-3ef2-fed7_98cc-80 { order 0 } } monitor /Common/gateway_icmp } …how can we easily replace every colon in the name : with \\:? In short, /Common/2001:668:fc78:0:f811:3ef2:fed7:98cc:vs6_2001_668_fc78_0_f811-3ef2-fed7_98cc-80 needed to become /Common/2001\\:668\\:fc78\\:0\\:f811\\:3ef2\\:fed7\\:98cc\\:vs6_2001_668_fc78_0_f811-3ef2-fed7_98cc-80. This must only be done on the lines with start with /Common and which also contain the string vs6. He could not guarantee that colons would not be found elsewhere in the file. ...

2019-09-11

Using SMS is like Killing Whales for Oil

If you’ve known me for a while, you probably know that I have a soap box. This soap box has “STOP USING SMS” written on the side in red Sharpie. It’s true. I hate SMS/MMS. The protocols are terrible and like hunting whales for oil. (Sure, you could do that, but why would you when there are so many better technologies out there?!) The Pain Points Slow Text messages are slow to deliver. Seriously. I often experience delays of several seconds (or tens of seconds!) waiting for text messages to send. This is especially true if I’m in my work’s office building which has many areas where cell signal is weak. ...

2019-08-15

Notes on sed

I’ve always been a bit hit-or-miss with sed and haven’t understood it to the level to which I wanted. Today I aimed to change that and these are my notes from sitting down to learn it. Replace a string in a file (first occurrence per line only): cat file.txt | sed 's/oldstring/newstring/' Replace a string in a file (all occurrences per line, i.e., globally): cat file.txt | sed 's/oldstring/newstring/g' Use your own delimiters by just dropping them in place of /: ...

2019-06-15