Daniel Nitsikopoulos The RSS feed for https://dnitza.com Wed, 07 Jun 2023 16:44:42 +0000 Wed, 07 Jun 2023 16:44:42 +0000 1800 Week 18 — Discovering Hyrule The weather this week was suuuper weird! It's like Autumn was throwing out one last hurrah. After a couple days of -6°C last week, we had some pretty warm ones this week. So much so that I had to carry my jacket on my walk to the shops! So long Autumn 👋

Zelda continues to be an impressive feat of game development. Switch hardware aside, the scale of this thing is immense! That immensity isn't padded out by a bajillion markers on the map pointing you to the same 5 kinds of quest. Instead you stumble upon Koroks (either hiding or looking for their friends), a builder who is eternally committed to holding up a sign, or a shrine that has been so well designed to allow for multiple solutions. That sense of discovery, I think, is what makes the game so good. You are essentially handed the keys once you land in Hyrule and then need to go exploring to figure everything out (which is incredibly rare in modern games). The other night, for example, I discovered "The Depths". Not by doing the introductory mission (I found that way later), but by diving in to a Temple! Nothing was broken by this apparent break in sequence, I wasn't hand held back in to the intro mission, I was just able to fuck around and find out!

One of my better moments handling the gliders:

Some friends of ours lent us Blockus the other week — short of Unstable Unicorns, this is the only game that Abby has been eager to sit down and play! It's one of those games that is super simple to pick up (it has 1 rule), but is surprisingly complex. You can plan ahead as much as you like, but you also need to account for the plans for 3 other players who either might have pans of their own, or are just taking it 1 chaotic turn at a time!

]]>
week-18-discovering-hyrule Sun, 04 Jun 2023 00:19:49 +0000
Week 17 — So long, Mercury I took down Mercury from the iOS App Store this week and have opened a PR to remove it from the Mastodon marketing site. I built it in my spare time over ~2018-2020, then hit a bunch of App Store Review roadblocks. With the inability to address bugs or add features as Mastodon improved its API, the app basically stagnated. I originally built the app for myself to address a couple of shortcomings with some of the other apps on the App Store at the time. But thankfully the fine folks at TapBots have come along with Ivory, and the Mastodon API has added a couple of the things that Mercury was doing client side. So now felt like a good time to pull it from sale. Anyone who installed it should still be able to use it. I have a longer post-mortem post in the works that I will post here shortly.

Bungie announced a new game set in the Marathon universe. I never played the game released in '94, but I am very much digging the aesthetic of this one, and I am interested to see what they do with the "extraction shooter" genre.

I was joking with someone at work that we had just hit negatives over night in Canberra when we had our first -1°C night and it's not even winter. This weekend we had 2 nights of -6°C and our house has been unbearably cold! I've re-applying seals to all of our doors / windows to try and keep as much of the heat in. I guess we'll see how we go on our next sub-zero evening!

Speaking of work, this week my (and may others) roles were officially changed. I am now officially a Team Lead (though the actual transition to the role happened a month or so ago). The role essentially encompasses tech lead, delivery lead, people manager and in the case of some teams, product-manager-lite. I am still trying to work out how to actually work in the role given it pulls in a bunch of disciplines that were previously their own distinct role. Books like The Manager's Path have helped somewhat, as have my experiences working in different teams! I am hopeful and keen to learn all the things, so we'll see how this shakes out!

]]>
week-17-so-long-mercury Sun, 28 May 2023 07:56:00 +0000
Week 16 — Four more months! This week's post marks 4 months of weekly posts! I have never really gotten in to the habit of writing (as much as I have wanted to), but I have found that even just writing these weekly posts has made it easier to get in to the habit of writing non-weekly posts! Now if I can just finish writing the other posts 😅

I've been making more blog updates this week. The updates have mostly been to the admin area as well as some smaller frontend details that were not previously possible in the version of Hanami 2 I was working with. I think the last outstanding piece (that I think needs a framework update) is to add active states to the main nav.

Speaking of this blog. I have been wanting to move to a cheaper and more environmentally friendly web host for a while now. I had been with Vultr for a while, and having a datacenter in Sydney was super nice when it came to SSH latency and deploy speeds, but the cost wasn't really justifiable — especially when other hosts offer better server configs for a fraction of the price. So, this weekend, I moved everything over to Hetzner. I had a bunch of rsync commands from the last time I moved server, so it only took a couple of hours. Most of which was moving all of the stuff in my Mastodon instance, and remembering how to install PHP again for my RSS setup.

I spent this morning out on Cooleman Ridge. There's an equestrian park on the west side of the ridge and so many people were out with their horses today. There was also a herd / troop / mob of Kangaroos just lazing around in the sun watching said people and their horses. I wanted to get a photo, but I couldn't without including a bunch of random people, so we'll have to settle for these:

  • A path up a hill and trailing off in to the distance.
  • A trail heading down hill with bushy hills in the distance.
  • A trail through the bush with a hill to the right and mountain on the horizon.
  • A trail through some light-density bush overlooking south Canberra
]]>
week-16-four-more-months Sun, 21 May 2023 05:51:02 +0000
Week 15 — Hiyah! It's Tears of the Kingdom time! I played the heck out of Breath of the Wild, and am so excited for this instalment in the series. I am not usually a fan of open world games, but that's usually because there's only a small section of actually interesting and compelling gameplay, that's then padded out with the same 5-10 side quests. Breath of the Wild was different though. It felt more like an immersive sim than another entry in the traditional open-world genre. This is mainly due to the way you could use Link's powers to puzzle your way through all the various encounters and shrines. I'm only a couple of hours in to Tears of the Kingdom, but the familiar clink and clunk of Link's gear as he runs around is drawing me back in to the world of Hyrule. Onwards and ... downwards?

  • Link sky-diving past the Zelda title screen
  • Link sky-diving towards a sky island with a dragon in the background
  • Rainy day in Hyrule
  • Link looking out at a sky-scape consisting of a number of distant sky-islands and a dragon flying upward

Ok, so next week is another short week. I totally forgot about this one, as it's not due to a public holiday, but rather a company mandated day off to refresh. We get one each quarter (except for Q3) and they're synced up across all our offices so that we don't come back in on Tuesday to a backlog of work that people have been creating while we are out.

It's also Mother's Day this weekend in Australia. To avoid the rush, we went out on Saturday for crumpets!

I've been doing some more work on some of the admin features of this blog over the week. Some notable additions include being able to create trips. A trip has a name and some a date range, and then through the admin UI, I can choose posts that happened during the trip to be part of the trip's timeline view. At the moment, this is mainly checkins and photo posts, since they've all come in from Instagram or Swarm.

I've also spent some time working on creating an image gallery for these post pages. I write posts in markdown, and don't really want to embed HTML in these pages where I can help it. So to overcome this, I am using some Javascript to wrap images in a list in a column layout instead, and then with Alpine.js I am popping those images in to a lightbox when they are clicked. It works well enough for now, and I am hoping the fact that the markdown is unopinionated will mean these posts can remain portable.

Autumn has been turning it up over the last few weeks as the remaining leaves turn. These are my two favourite trees to watch (not clean up after 🙄) as the seasons change (both in to Autumn and in to Spring).

]]>
week-15-hiyah Sun, 14 May 2023 07:56:45 +0000
How I debug with Ruby Over the many years that I have been working with Ruby, I have never really learned to use a debugger, and really only lean on tools like Pry to start a REPL session at a particular line in some Ruby code. From there, I reach for Ruby's built in debugging tools, and thus far, they have served me well! Below is a non-exhaustive list of some of the common techniques I use to work out what the heck is going on with some piece of code.

How do I work out what methods are available on a class?

The methods method lets you see which methods an class defines. This is useful when working with an un-documented or otherwise unknown class, but have an idea of what you might want to achieve. The return value of this call is an array of symbols that represent method names.

Foo.methods #=> [:bar, :baz, ...]

If you run this yourself on a class, you'll see a huge list of method names, including things like :new, :==, :inspect. This is is because method also returns a list of methods that the ancestors of your object respond to. If you want to clean up this you can:

Pass the false argument in to methods:

Foo.methods(false) => [:bar, :baz]

Or selectively remove the methods of known ancestors from the resulting output:

Foo.methods - Object.methods => [:bar, :baz]

There is also the instance_methods method that does the same thing, but only returns instance methods.

The following calls are almost the same:

Foo.new.methods #=> includes methods that belong to ancestors

Foo.instance_methods(false)

Ok cool, now we have an idea of the methods, but what about actually calling them?

The parameters method lets you take a peak at the arguments required to call a method. This is not always bulletproof, as some methods take a variable number of args (e.g. def foo(*args))

Anyway, once we have a method to inspect, we can use parameters like so:

class Foo
    def bar(one:, two:)
    end

    def baz(one, two = nil, three: nil)
    end
end

Foo.instance_method(:bar).parameters #=> [[:keyreq, :one], [:keyreq, :two]]

Foo.instance_method(:baz) #=> [[:req, :one], [:opt, :two], [:key, :three]]

You can even see if a method has a default provided (:key, :opt), or is required (:req, :keyreq) along with its name.

Workout where a method is defined.

Sometimes, you're calling a method and the behaviour being presented is not at all what you expect, or even worse, your myriad of puts and raise calls you've put in place to debug the behaviour are not being called!

Here's an example:

# source/foo.rb

class Foo
    def bar(arg)
        raise "here".inspect
        # do the method here
    end
end

Foo.new.bar(arg) #=> Nothing is raised 😱

Inspecting the bar method with source_location should help work out what is going on here:

Foo.instance_method(:bar).source_location #=> ['some_monkey_patch.rb']

In our case here, we can see that something else is being called instead of our method in our class! While this exact example is not super common, I have been bitten by this a couple of times by some gems implementing a to_h, to_json, to_s etc. method on basic Ruby classes that then cause unexpected behaviour.

Another variation of this is when you have a super-class that is calling super in its initialiser (or some other place) but you don't know where that goes.

class Foo < Bar
    def call
        puts method(:call).super_method.source_location #=> ['/gems/path/bar.rb#42']
        # super
    end
end

You can then use something like cat in the terminal to inspect the file and get a sense of what Bar's super method will call.

Or better than cat, you can use bundle open to dig around a gem with your editor of choice (discussed in the next section).

Inspecting a Gem

Sometimes, the code you're having trouble with is in a gem! There are a couple of ways to go about inspecting this code. If the code is hosted on Github, then that's a fairly simple way of spelunking through code, with the benefit of having commit messages right there that could explain the behaviour you're seeing (just make sure you're looking at the right version).

But, you can also use bundle open gemname to have bundler open the correct version of the gem in your EDITOR of choice. From here, you can throw in debugging statements, make changes, and even fix a bug or two if you find any :)

If you're spelunking has lead you to drop puts statements through many files, you can clean the gem up quickly with gem pristine gemname (or gem pristine --all if your debugging journey spanned multiple gems!).

How did we get here?

We've discussed working out where a method call will take us, but what about how we got to a particular method.

For this, we can use caller. caller will print out a massive stack trace showing you how we got here, but the first line is the one that really matters:

class Foo
    def bar
        caller
    end
end

irb(main):072:0> Foo.new.bar #=> ["(irb):72:in `<top (required)>'","/Users/danielnitsikopoulos/.asdf/installs/ruby/3.2.0/lib/ruby/3.2.0/irb/workspace.rb:119:in `eval'", ...]

in this case, I'm running the code in irb, so (irb):72 is where this is being called from.

Formatting

The last thing I want to touch on, is how to do some basic formatting to make inspecting output a little easier.

Add some markers to split puts calls, especially when calling something in a loop:

def foo
    puts "Doing something:"
    do_something
    puts "*" * 88 # print out 88 stars
end

2.times { foo } #=>

Doing something:
****************************************************************************************
Doing something:
****************************************************************************************

When looking through a collection of data to understand something about it, also print out things like IDs so that you can pick out the one you want:

some_collection.map {|c| [c.id, c.name] } #=>
[
  [123, "foo"],
  [234, "bar"],
  [345, "baz"],
  ...
]

Conclusion

Ruby's built in meta programming tools are super powerful, and while there are definitely a bunch more techniques for debugging, these are the ones I always turn to first and usually are all I need to work out what is happening. I will (one day) get RubyMine's built in debugger working and report back if it blows any of this out of the water :D

]]>
how-i-debug-with-ruby Sun, 07 May 2023 07:29:47 +0000
Week 14 — Blog updates
  • Regular length week this week ;)
  • I have been adding some behind the scenes features to this blog. Up until now, I have been using a handful of micropub clients, and some Ruby scripts to publish and manage posts. This has all been working well thus far, but the micropub spec doesn't include general admin features (like managing tags). So, I've setup a new Hanami slice to handle some admin functions. For now this just includes the ability to remove tags, and to setup auto-tagging for posts based on their content or title.
  • I've also setup a new movies page based on movies in my letterboxd. For now, it's pretty static, but I am hoping I can sync it up to the RSS feed of my profile so that new entries come through.
  • I played a bit of Hitman 3over the weekend. I picked it up and started it when it came out, but never got around to finishing the last few campaign missions. I've only got a few left to go, but jumping back in has reminded me just how much of a masterclass in game, level and puzzle design Hitman 3 is. Where Doom was all about finding the red key to get through the red door, Hitman is about finding any possible way around that door with, or without the key — all the while dressed in some wackadoo disguise trying no to get caught.
  • We've been churning a few more pizzas out of the pizza oven this weekend, and I think that we're finally on to a reliable technique. We didn't get a thermometer with the oven, so it's been a bit of guess work to understand when the oven is ready to cook. The general guidance is 15 mins once lit, but that previously resulted in slightly undercooked pizzas. Turns out waiting ~20 mins or so, was the ticket — as was rolling out thinner dough :D
  • ]]>
    week-14-blog-updates Sat, 06 May 2023 11:12:15 +0000
    Week 13 — Another longie
  • Yet another long weekend, making for a short week :D Though I think this is the last longie for a little bit now. This time, we were off on account of ANZAC day. The public holiday fell on a Tuesday this year. Some folks took the Monday off for an extra long weekend, but we both worked and took the Tuesday to go for a hike through Tidbinbilla. We've been working our way through the tracks there, but it's been a while since we last went, so we took it easy with the Ashbrook Fire Trail. The trail is a there-and-back-again style trail (not a loop) and is bookended by a couple of small river crossings. The first crossing was fairly simple, but the second was not possible with the shoes we had picked for the walk. It has been raining pretty steadily in Canberra, and so the rocks and bits that we could have used to cross were all well under water. This meant we had to turn back with about 300m to go before the "official" end — so I guess we have to go back to tick that one off.
  • I went for a bi-monthly haircut this weekend. While this isn't something to write home about, I somehow managed to get lumped with a barber who was a Trump apologist. And it's one of those things where, I never know what to say. I absolutely don't want to start a conflict with someone cutting my hair, and I doubt it would change any minds, but every fibre of my being was struggling to even participate in the conversation. This is not the first time this has happened, and it probably won't be the last, but I will continue to be baffled by people's allegiance to that man, especially when they live in a small city in Australia.
  • My music player journey is continuing, and this time on iOS. I picked up Marvis Pro and it has been amazing! I mainly picked it up for last.fm support, but it is also incredibly customisable. It allows for customisation of some of the expected bits, like the now playing screen as well as some theming options. But what I wasn't expecting was the ability to essentially build your own home screen out of static and dynamic sections. Now I can intentionally include sections like "recently added", "playlists" and some smart searches to surface albums I had forgotten about and drop all of the radio station clutter that Apple's Music client adds in. On top of this, these custom screens can be shared with other folks using Marvis, so as you can imagine there is a pretty lively community of people sharing their customisation discoveries in the form of their home screens.
  • ]]>
    week-13-another-longie Sun, 30 Apr 2023 07:04:53 +0000
    Week 12 — Layoffs
  • This week has been rough on many fronts. Layoffs at work have meant we have lost some of the most brilliant people I have had the chance to work with. Some had been with us for a good chunk of their career and the company's life. It's tough seeing so many smart and talented people needing to now scramble for work in already uncertain times.
  • Not much has happened outside of work this week. I did make some more progress on clearing away brush from the shed, with just one large bough remaining. This bit fortunately grows up and over the shed, so we have decent access to most sides of it now and can start working out if we want to remove it or replace it with something smaller that is big enough to hold just what we need.
  • We also have family visiting this week, which is a nice distraction to all the goings on :) For some reason mid-late April is when we have historically hosted visitors. It also happens to be the time of year when Canberra shifts quickly in to may-as-well-be-winter-mode. Which catches people who are used to Melbourne autumns off guard.
  • The avo is starting to recover a bit! And there is another sprouting next to it. I think I might move it outside undercover for a bit so it can get some unfiltered sun, but not be bitten by the frost that will inevitably roll in over the next few weeks. A tall avocado sapling with 3 leaves An avocado seed beginning to sprout
  • ]]>
    week-12-layoffs Sun, 23 Apr 2023 00:42:31 +0000
    Week 11 — Easter
  • Another short week this week on account of Easter, which was nice! Speaking of, Greek Easter is this weekend — so Χριστός Ανέστη to all who celebrate :D
  • I've been working on clearing out all of the brush around our shed over the last few weekends. There's a growing number of piles of twigs, leaves and bigger branches to go in our green bin, but I am mostly excited to mulch the smaller branches to scatter around the trees and plants we do want to keep :) Once the shed is clear, we can decide if we want to keep it there or not, but right now being hemmed in by bushes and small trees is making it hard to decide. The one benefit it does give us (other than storage) is that it blocks sight-lines over our meter-or-so-tall back fence in to our neighbours yard.
  • I've been getting back in to Magic the Gathering this week. The iPad app is super nice, and (so far) it's not as predatory as many other free to play games. They give you a bunch of starter decks, presumably as some kind of core set, and it's currently more than enough to be able to play around with some interesting decks!
  • We've been subscribed to Thieves coffee for a little while now, and while the variety is good, it can be tricky to remember which beans were decent and what was good about them. Last year, I saved all of the bean bags and wrote some notes on the back of them. This worked OK, but I have been looking for something that is a bit more solid, in terms of going back to find good beans and brew methods. I recently found Tasting Grounds (excellent name) which basically fills all I am after in terms of keeping track of various beans and the results of brew methods I try with them. My notes on the old bean bags aren't as detailed as what is available in Tasting Grounds, so I probably won't backfill them, but I am glad to have something decent going forward!
  • I've also been chipping away at updates to this site over the last few week nights. A couple of new pages and a couple of new ways to explore posts should be ready to go in the next couple of days!
  • ]]>
    week-11-easter Sun, 16 Apr 2023 05:12:43 +0000
    How I use Obsidian I've been using Obsidian for a little while now. At first, it was largely just a replacement for Notes.app, like Ulysses before it, I preferred it purely because I could see the markdown files that it was saving. As time went on though, I would pick up some new bits from folks at work who also use Obsidian, or from podcasts or blogs I subscribe to. It's now become a big part of my life on macOS and iOS — right up there with iTerm or Safari.

    Writing documentation

    Almost any piece of documentation I write for work starts its life in Obsidian. I have a vault just for work docs that doesn't get synchronised and lives on my work computer, but means I can write outlines and drafts out and publish a doc when it's ready. Not to mention having a local backup in case Confluence decides to crash and lose my work — though, to be fair, this is happening a lot less lately.

    Daily notes and to-do lists

    This is where Obsidian really shines in my opinion. I used to use Taskpaper for plain text daily to-do lists. And by daily to-do lists, I mean a single long list that I would keep adding things to / checking things off from. While this was kind of neat in the sense that I have a historic list of all things I've don, the method for organising those to-do items was a bit unwieldy. Each day I would need to tag an item with @today if I wanted it to be visible in the "today" view. Booo 👎🏼.

    Obsidian has a built in concept of a "Daily Note". Right from the command palette, you can "open today's daily note" and if there isn't one, Obsidian will offer to make one for you. Of course, where this note is saved and its filename is customisable. But the cool thing is, you can also install a plugin to create a daily note from a template!

    My daily note template is as follows: - A created at timestamp - A tag of "Daily Notes" - A section for a to-do list - A section for notes, tagged with #daily_note (more on why in a bit).

    created: <% tp.file.creation_date() %>
    ---
    tags:: [[+Daily Notes]]
    
    ---
    
    ##### ✅ To do
    - [ ] 
    
    ---
    # 📝 Notes
    - <% tp.file.cursor() %>
    
    #daily_note
    

    So now, whenever a daily note is created, it's labeled with the day's date and the cursor is placed in the notes section, ready to go.

    There is one more plugin I use though, to make this setup really work for me. And that is a plugin to roll-over any to-dos from the previous daily note to today. This way I still have the history of what was done when, but not all the clutter or manual work of tagging when a task should appear.

    So when I first log in for the day, I'll usually open the day's daily note and clean up whatever to-do items are rolling over, add any new for the day and then be good to go!

    Plugins to make this happen: - Templater - Rollover Daily Todos - Calendar is also nice. It adds a calendar to the sidebar so you can jump to any daily note, without having to search.

    Reviewing daily notes

    I mentioned that I have a #daily_note tag in the notes section itself. The reason for this is that every 6 months or so at work, performance review season rolls around. And, in what I am calling a weird coincidence, every 6 months or so I wish I had taken notes about what I had done for the previous 6 months. This is where the daily note tag comes in. My mate Mike put me on to another plugin called Dataview which basically lets you query your Obsidian vault. He also shared with me this script (below) that will search for notes in a folder with a given tag, and then pull the notes in to a view broken down by month and year.

    So now, whenever I am taking notes in meetings, or when I am puzzling something out, I throw a #daily_note on the end of important lines and violà, a prompt and a fighting chance of remembering what I did in the last 6 months.

    // get daily notes pages
    let pages = dv.pages('"Daily Notes" and #daily_note').sort(p => p.file.cday)
    
    // group pages by year
    let years = pages.groupBy(p => p.file.cday.toFormat("yyyy"))
    
    // for each year...
    years.forEach(year => {
        // add a header
        dv.header(3, year.key)
    
        // group by month
        let months = year.rows.groupBy(y => y.file.cday.toFormat("MMMM"))
    
        // for each month...
        months.forEach(month => {
            // add a table with the month name as header
            // and each item for that month in the body
            let file = month.rows.file
            dv.table(
                [month.key], 
                file.
                    lists
                    .where(item => !item.task)
                    .map(item => ["- " + item.text]))
        })
    })
    

    Writing these posts

    I also use Obsidian for writing my weekly posts and posts like this one! While I wish it had better Micropub support, I make do with a Ruby script that pulls in Jekyll-like markdown files and converts them to the JSON that Micropub expects.

    ]]>
    how-i-use-obsidian Mon, 10 Apr 2023 08:33:47 +0000
    Week 10 — Double digits 🎉
  • I've been trying to get back in to scrobbling things I listen to to last.fm again. Partly so I can display the week's top track at the bottom of these posts, but also because I looked back at my scrobbles from 2008-2009 and found some tracks I had totally forgotten about! So in 15 years from now, if last.fm still around, I'll have that history to look back on. Sadly though, Apple Music's last.fm integration story is abysmal. On iPhone, you need to have the track in your library, and then remember to open the last.fm app to manually hit sync every now and then. There is an app that alleges to automatically scrobble for you, but I have yet to see it work. On the Mac, at least the last.fm app still exists, but I have also found that to be flaky, and it manages to keep getting blocked by work's security *waves hands* stuff. I have found https://cider.sh for the Mac to be a good Apple Music replacement though, and it has built in scrobbling, which means there's no need to rely on my memory to launch a second app. On the iPhone, it looks like Soor or Mavis Pro can act as drop in Music.app replacements, though I have yet to try either of them yet.
  • It's the easter long weekend this weekend. I am very much looking forward to 4 days off, after what has been a series of very chaotic weeks. As I write this, it's pouring down outside, and it's reminding me I need to clean my gutters — but that can be a tomorrow task :)
  • I wrapped up the "good" ending of Tunic this week. One of the things that frustrates me about adventure games with strong puzzle or mystery elements is the need to run around like mad trying to find said puzzles. Tunic overcomes this by putting all of the puzzle hints in the manual — then you just need to find the manual pages, which can be done mostly just by playing the story through and following hints on other pages. The only thing I needed to look up was how to decipher the game's language (because who has the time to figure it all out 😅). As I closed the game the other night, I noticed yet another unsolved puzzle, so I may revisit it next week to see what that is all about!
  • I have a couple of walking routes that I follow when taking the dogs out. Some go via a nearby school's football ovals, others via some bush-land. This week, I set out to try and find some new ones. I didn't have much luck, but I did discover a bunch of walk ways that cut through whole blocks, meaning I can get further away from home, faster and explore different paths back. We shall see how we go through the rest of the week!
  • ]]>
    week-10-double-digits Fri, 07 Apr 2023 02:51:34 +0000
    Week 9 — Pizza time
  • We've recently purchased an Ooni pizza oven 🎉. Our closest Good Pizza Place™ is a 40min round trip away. Which is fine if we can eat in, but because the pizzas are so thin, they travel incredibly poorly! We used to have a pizza stone for our oven, but that a few years ago in a cleaning mishap. We planned to replace it with a pizza steel, but the pull of a wood-fired pizza oven was too powerful! Expect more pizza and pizza-adjacent content in the future :)
  • Daylight savings time ends this weekend. This means we're back to GMT +10, with much longer stretches of darkness in the evenings. I guess the only advantage is now I can get up early to walk the dogs and not be walking around in darkness 😆
  • Abby and I have been playing Tunic (Wikipedia) on the Switch. It's a Zelda-like in that there's fairly simple (yet difficult) combat, mixed with some puzzle solving. There is a beautifully illustrated in-game manual that starts off pretty bare (only a couple of pages), and slowly fills out as you discover more and more pages. The game also has its own language, which is possible to start piecing together through context clues and repetition. So the combo of no manual, and a foreign language makes for a great mystery and brings back that feeling of playing an old Playstation game that your mate managed to find a Japanese version of.
  • Greek easter is almost upon us, and the Greek bakery out in Gungahlin has started selling tsoureki! It's not even close to my yiayia's recipe, but it is still very tasty and nice to be able to get a hold of for a few weeks of the year :)
  • The avo is not looking so good this week. I think I may have over watered it now that the days are cooler, and some of the leaves have curled up 😬. I do have another seed that has just sprouted some roots, so if this one doesn't make it, there could be a backup!
  • ]]>
    week-9-pizza-time Sun, 02 Apr 2023 06:29:58 +0000
    Week 8 — 🍂
  • It's been a bit f a quiet week this week — well, at home anyway. Work has been full on, and maybe that has contributed to the quietness of the week.
  • Contrary to what I mentioned last week, the weather has started to turn here in Canberra. While it's not icy yet, we've been seeing tops of around 20 over the last week with a bit of rain.
  • With the weather change comes one of my favourite times of the year, too! My regular route in to the city goes via the National Arboretum, which is quite a sight to behold as it comes in to view around the bends of the parkway.
  • I spent Monday working out of a co-working space nearby. It was nice to be working around people again :) The space itself is quite nice, but the desks, chairs and shared video-call rooms are a bit hit and miss. One of the Zoom rooms I used had graffiti all over the fold out table, which makes wonder — why you would pay to use a nice space, and then draw all over the desks! 🙃
  • We watched Everything Everywhere All at Once this week. What a ride that was! I was not at all expecting anything that happened past the first 10 minutes of that film, and I loved every minute of it. 10/10, would experience again!
  • The avo is doing well, and now that we're getting in to autumn (and a Canberran autumn at that), I might look at cleaning up some of the top growth to try and encourage this little thing to fill out some of the lower parts of its trunk 🪴 An young avocado plant with 9 leaves
  • ]]>
    week-8 Sun, 26 Mar 2023 11:10:57 +0000
    Week 7 — Same same, but different
  • I finished the Lightfall campaign this week on legendary! It was pretty amazing knocking over the last encounter solo. It took me a bit of bumping up against the whack physics in Destiny, but got there in the end :) The missions and setting were more to my liking than The Witch Queen, but the story and writing just felt so awkward — especially this close to The Final Shape. I just hope a bunch of the major details introduced in this expansion get addressed as the seasons play out.
  • The dogs are well on the mend this week! A few days of probiotics had them back to their normal selves in no time at all. Nothing worse than a sick pet and the guessing game of what might be causing them grief!
  • I had a couple of super long meetings at work this week (~3hours or so on Zoom). I have to say, headphones with transparency mode go a long long way to reducing Zoom fatigue. I found myself straining to listen out for things happening around me with traditional headphones, and getting a mix of house noises and people's voices makes for a more natural listening experience.
  • The weather in Canberra has continued to be weird for this time of year. We're back up in the 30s again. Only a month away from ANZAC day (when things start to get properly cold) and I'm still running around in shorts and a t-shirt!
  • The new avo growth has been coming up nicely :) I took a couple photos of it during the week as it sat here on my desk. After some rudimentary lining up, I gave the images to an AI and it interpolated them in to the video below! 3 new leaves on an avocado plant growing
  • ]]>
    week-7-same-same-but-different Fri, 17 Mar 2023 09:46:05 +0000
    Week 6 — Sleepless in CBR
  • This week, the temperature has cooled way down in Canberra. I've had to double up on long sleeve shirts some days to stay warm, and some of the leaves on our trees are starting to turn 🍂
  • I've been playing through the new "Lightfall" campaign in Destiny 2 on legendary difficulty and it has been fun! I'm not super in to the new sub-class yet, but I guess that's because I've only played it as part of the campaign (and because fusion grenades + starfire protocol is just so much fun).
  • Crumpet is prone to seizures, and while she's been pretty good over the last few months, she had one again on Wednesday. We (so far) haven't been able to work out what could be causing them. Our suspicion was stress, but since we have made some changes to reduce the stress she may have been under, she still seems to have them. Her last one was in January, and the only line we can draw between them is that I forgot to feed her on time, so our current theory is it's blood-sugar related.
  • I swear our house has been cursed this week 😅. Both dogs are having some digestive distress, needing to get up at all hours of the night to go outside. Our smoke alarms are also weirdly going off in the middle of the night too. This has made for a week of sleep deprivation. Both pups are looking to be on the path of recovery this morning ❤️ Two dogs curled up in my lap
  • I signed up for first #rubyfriend a few months ago, and found someone to mentor only recently! Our first chat was great, and I am glad that there are still new web developers getting in to Ruby as their first language (over something more trendy)! It sounds super challenging for junior engineers out there right now, and it sounds like some places are interviewing juniors as if they're at the mid-senior level.
  • New shoots are growing on the avo this week! New growth on an avocado plant
  • ]]>
    week-6-sleepless-in-cbr Sat, 11 Mar 2023 01:04:32 +0000
    Week 5 — Plant's alive!
  • I've been working on the backend of this blog to pull in all the stuff I have, from various places of the internet. So far, that's been photos off of Instagram as well as places I have checked in to on Swarm. It's been a bit of fun to build in these fairly simple features, free from performance constraints and the like. Since everything on this site is a "post", the most involved part has been working out how to store images such that when I want to move hosts later, or split asset and web hosting, nothing breaks. Where I have landed with that is to save absolute image URLs on posts, and then later, I can proxy requests for images (that match the current storage pattern), to wherever the new host is. Or update the persisted image URLs to have the new host 🤷🏽‍♂️.
  • Went and saw Alexisonfire on Saturday, and holy shit, what a show!! They played tracks from their entire discography, and every, single, one, was a banger. As each song faded out, the crowd would clap and cheer, and as the first few bars of the next song rang out, that cheering would turn in to shouts of surprise and joy. It was amazing to feel that energy again after a few years off, and I hope they make it back in less than a decade and a half this time!
  • We've been catching up on the episodes of The Last Of Us that were on while I was away. It continues to be a good show. I appreciate the extra mile they're going to build all of the characters up. It's a far more interesting approach than the main story arch, but I am keen to see that out to hear Abby's thoughts on Joel's decision to ultimately save Ellie.
  • The avocado has grown so much in the last 2 weeks! I was kind of worried because I watered it enough for a week, but it was relatively hot and dry in Canberra while I was gone. Thankfully, all that was for naught! 🌿🆙 A small avocado plant with 7 leaves. 6 of which are about 15cm long each
  • ]]>
    week-5-plants-alive Sat, 04 Mar 2023 11:04:26 +0000
    Week 4 — Meet the team.
  • I am coming to the end of my week in Melbourne. It's been a great little week. Taking the train to work continues to be a novelty as does getting home past 7pm. I don't know how I managed to do that in the pre-work-from-home days, and I don't think I could do it for longer than a week, but it was fun while it lasted.
  • I met my new team IRL for lunch this week. It was nice to be able to just chat face to face without needing to stare at a computer screen, or feel the need to sit in silence while someone else talks in fear that speaking will do something weird to Zoom's audio. We also got to do a bunch of in-person work, which made for some satisfyingly productive pairing sessions.
  • I checked out The Keys on Thursday, a warehouse converted to a bowling alley / bar / bistro / arcade. It's been a long time since I've been to a bowling alley that had decent drinks, food and atmosphere. A++ would bowl again 🎳.
  • This week, I have been thinking a lot about how best to reduce the use of the Active Record pattern within our Rails monolith at work. I think I have a relatively neat solution that involves a repository layer that returns value objects, that can then be composed with queries. Repositories would still use Active Record under the hood to read, and there would need to be some work to represent computed properties, but I think it could work! I plan to write this up more fully soon.
  • I've dropped of getting through the Metroid Primer remaster this week, even though I brought my Switch with me, there just hasn't been a moment that I've been able to pick it up!
  • No updates on the avo this week — soooon!
  • ]]>
    week-4-meet-the-team Fri, 24 Feb 2023 11:52:45 +0000
    Week 3 — Ruby Ruby Ruby.
  • I've been listening to the latest The Adventure Zone campaign, Steeplechase . Based on the Blades in the Dark tabletop RPG, it seems to be a much faster paced campaign as compared to some of the other DnD based campaigns. So far I am quite enjoying how the system works, as well as the story.
  • I have been listening to the aforementioned podcast while commuting to the office as well as to Ruby Conf over the last few days. I haven't really missed the ~60min commute to and from the city each day, but it's kind of a novelty while I am in Melbourne for the week and being able to make more of a dent in my podcast backlog each day has been kinda nice.
  • Ruby Conf 2023 was packed with amazing presentations, and as always the balance of non-technical and technical focused talks was great to see. Some of the standout talks (to me) were:
    • Upgrading the Ruby Community by Pat Allan— Pat challenges the audience to think more critically about the Ruby communities moto, MINASWAN, suggesting that nice might not be good enough anymore.
    • The World Set Free by Coraline Ada Ehmke — Coraline chats ethics as it pertains to technology and politics. Highlighting that technology has never been apolitical, and never can be and that we as developers of software need to be constantly aware of how our work can be used to further exacerbate power imbalances.
    • REACT to Imposter Syndrome by Prakriti Mateti — Prakriti talks strategies for interrogating whether a particular negative thought is being caused by imposter syndrome, and how to re-express said thoughts so as that they're more accurate and constructive.
    • How Puma Works by Nate Berkopec — Nate talks about the internals of Puma and how to become an effective open source contributor all while racing against auto-advancing slides! This one was a particular standout to me, as I've always wanted to dig in to Puma's internals, but never knew where to start. Thanks Nate!
    • All you need is Rails (Engines) by Julián Pinzón Eslava — Julián explains how he compartmentalised a Rails app using engines, and the various hurdles he faced along the way. Having not used Rails, let alone Rails Engines in a long time, this one resonated with me as it largely followed the "Slices" feature of Hanami
    • A People Pleaser's Guide to Salary Negotiation by Colleen Lavin — Colleen gives us the advice we all need to hear about how to negotiate pay when going in to a new role.
    • Security Doesn't Have To Be A Nightmare by Wiktoria Dalach — Wiktoria delivers one of the best talks I have seen on security. The delivery is perfect with sharp and to the point take aways. I have always been a proponent of shifting security left (earlier in the delivery timeline). Wiktoria gives us the evidence for why and the questions to ask to make sure everything is covered off.
    • Implementing Object Shapes for CRuby by Jemma Issroff — Jemma gives a stellar run through of how the internals of Ruby's instance variable management works. Comparing the process between Ruby 3.1 and 3.2 made it easy to see where the performance gains are in Ruby 3.2, and why the changes made were necessary. Jemma also paired with Aaron Patterson in late 2022 on the implementation of Object Shapes. The video is highly entertaining and educational, I recommend it.
  • Talks aside, it was lovely getting to see some humans again, some of which I haven't seen since Ruby Conf 2020 😅
  • Since I am away from home this week, I am not sure how the little avo is doing, so watch this space as we all find out next week 🥑🌱
  • ]]>
    week-3-ruby-ruby-ruby Fri, 17 Feb 2023 23:34:24 +0000
    Week 2 — Next week, and next week.
  • Nintendo dropped a surprise release of Metroid Prime Remastered on us this week! I remember reading, and re-reading all of the promotional material of the original when it was announced out in ~2001. Then being amazed by the detail in Samus' visor alone. The way it fogged up with alien steam and the way bright lights caused Samus' eyes to reflect off of it was just magical at the time. I've tried to replay the Gamecube version via emulation a couple of time over the years, but was always put off by poor frame rate and weird texture compression. I'm so glad a remaster has dropped for modern hardware and I can't wait to spelunk through the world of Talon IV once more.
  • Performance review time has been rolling through at work. I always find that I can write for days when providing feedback and praise for someone else, but hit a mental block when I need to write something reflective. Time and time again, I tell myself I'll keep a list of things throughout the year so that come performance time, I can whiz through the list and write up a self reflection with ease. It always starts strong, and then drops off a cliff after about a month or so. Let's see how we go this year.
  • This week is the penultimate week that my team at work gets to work together as a team before we disperse to join and form new teams. It's been a wild 12 months, and I'm looking forward to the things we get to tackle next!
  • I am off to Melbourne next week for Ruby conf. I am super excited to see some Ruby humans in person again after a few years off :)
  • I also managed to snag a couple of tickets to go see Alexisonfire the week after Ruby conf. in Melbourne. The last time I saw them was around 2008? so very keen to see them again!
  • Vim practice has been going well, finding the right plugins to do the things I am used to in RubyMine has been kinda fun, though I've had to start a cheat sheet because I'm starting to lose track of some of the less frequently used commands.
  • The avocado plant is doing well too! The new growth is maturing and some of the leaves that were curling last week are looking better. A small avocado plant with a few leaves of new growth
  • ]]>
    week-2-next-week-and-next-week Fri, 10 Feb 2023 11:17:23 +0000
    Week 1 — This time, for sure.
  • 📲 New blog, who this? I have been re-building this site with Hanami & Tailwind, following the W3C's Micropub spec (mainly so I can leverage plethora of amazing compatible clients out there to write posts like this).
  • Since the enshitification of Twitter, I have been reflecting on the permanence of the things I put online. Not that I want the things I put online to be there forever, but more that I would like to be the one to control when they go away. To that end I have moved to self-host the things I consider to be important. Right now that is this blog, a single user Mastodon instance, and my RSS aggregator.
  • A little while ago, Hanami rolled out its 2.0 release. As a long-time fan of rodakase and the dry-* ecosystem of Gems, it's super exciting to have a modern framework in Ruby-land. Towards the end of 2022, my team at work spun up a brand new product over the course of 3 months or so, using one of the later betas of Hanami. The service has been rock-solid, and includes things like a mock data layer that can be optionally swapped in for the live data layer to make things like local development and demo data generation possible. This was made maddeningly easy by Hanami's provider API. I didn't get to write much of the code for this, and as such have re-written this site in Hanami, and I plan to open-source it soon!
  • Abby and I have been watching The Last of Us, and gross retconning of the origins of the parasite aside, it has been pretty enjoyable. It's been a long time since I played the game, so I have totally forgotten some of the smaller story beats. This week's episode was an incredibly touching arc of the lives of Bill and Frank. Characters, who, in the game were only hinted at being romantically involved. HBO took this, ran with it, and made the room incredibly dusty for about 2 hours. Helluva backstory just to explain how Joel was able to pick up a spare car battery.
  • I'm trying Vim again for reals this time. I am not writing a whole lot of code these days, so the overhead of Rubymine just to read some code, or make some small changes here and there is just too much. My previous attempts at learning Vim were made tricky by wanting to be as productive as I was in an editor like VSCode or RubyMine. Now that I'm not so much on the critical path of getting code out, this might be a good time to learn. So far, it's been pretty enjoyable, and since I have iTerm open all day anyway, there's one less thing to keep running.
  • I have been growing an Avocado in a pot on my desk. It looked a bit shaky after I repotted it from a smaller glass container. But this week there's been some new growth! A small avocado plant with a few leaves of new growth
  • ]]>
    week-1-this-time-for-sure Fri, 03 Feb 2023 08:23:08 +0000
    Ruby learning materials. I often get asked about recommendations for resources to learn Ruby (and how to program, generally). This list is intended to catalogue the various resources I have shared over the years and be an easy reference point for future learners.

    Ruby Koans

    https://www.rubykoans.com

    This is my go to recommendation for learning the Ruby language from scratch. You'll complete a number of exercises in the form of tests. Your goal is to get each test to pass by writing Ruby code. As with most $language Koans library, it starts off very easy and then ramps up in complexity.

    The Odin Project

    https://www.theodinproject.com

    Specifically the Ruby portion of the "Full Stack Ruby on Rails" course. This course covers off almost all of the basics that you would need to be productive with Ruby in a project that isn't super complex.

    Ruby Weekly

    https://rubyweekly.com

    One of the joys of the Ruby world is that someone is coming out with a Cool New Thing™ almost all the time. This can be hard to keep track of, and I have found Ruby Weekly a great resource to keep on top of all of the happenings in the world of Ruby. There are similar newsletters from the same publisher for other languages, too.

    Ruby Tapas

    https://www.rubytapas.com

    These timeless videos from Avdi Grimm illustrate the why behind a lot design patterns we employ every day, using real examples to help solidify the benefit of following these patterns.

    Blogs

    Podcasts

    • The Bike Shed — Out of thoughtbot, general developer experience, challenges and joys, usually covering Ruby and Javascript.
    • The Ruby on Rails Podcast — A weekly chat about Ruby on Rails, OSS and programming in general. Though not always about Rails specifically.

    Talks

    Boundaries

    Garry BernhardtWatch

    Thinking about the boundaries of and within systems can be tricky for new programmers. This talk does an excellent job of introducing the topic and providing concrete examples to take with you throughout your career.

    Y Not- Adventures in Functional Programming

    Jim WeirichWatch

    A detailed introduction to functional programming with Ruby, via first principles of lambda calculus.

    Refactoring Ruby with Monads

    Tom StuartWatch

    Dealing with unwieldy code using monads to help simplify presence or absence of data in our apps.

    All the Little Things

    Sandi MetzWatch

    Another journey through a hairy refactoring, this talk takes an ugly section of conditional code and converts it into a few simple objects. It bridges the gap between OO theory and practice and teaches straightforward strategies that all can use to improve their code. Also, checkout Sandi's book at Practical Object-Oriented Design, An Agile Primer Using Ruby.

    ]]>
    ruby-learning-materials Mon, 30 Jan 2023 08:37:22 +0000
    Deploying a Hanami 2.0 app to fly.io. I have a couple of small hobby apps that were on Heroku's free tier (RIP) that I have now moved over to Fly.io. Fly.io has a migrate from Heroku process for Rails apps, but as far as I could see, not for any Ruby app. So I had to do things manually, and while deploying to Fly.io is super simple, there were a couple of small things that tripped me up that I thought I'd write about here in case any one else is also trying to deploy a Hanami 2.0 app to Fly.io.

    Getting setup

    After you've setup an account on fly.io and have installed the command line app, you can then follow the docs for setting up a Ruby app.

    While running through the fly launch setup, you should get the option to setup a Postgres database. If you do, the URL will be available as an environment variable in DATABASE_URL.

    Once fly launch has completed, you should have a new fly.toml file in the root of your project.

    Before deploying your application, you'll need to make a couple of changes specific to Hanami 2.0. The fly.toml below is where I landed in terms config for a small, simple app. The biggest changes from the generated file are as follows:

    • on deploy, defines a release command to run database migrations (at the time of writing, migrations are not in Hanami 2.0 by default)
    • defines the web process as bundle exec puma -C config/puma.rb
    • sets the Hanami environment
    • configures the processes to run (as ["web"]) and the internal port to listen on

    Deployment

    Once you've filled out your fly.toml, you can run fly deploy to send your first build to fly.io.

    If you're familiar with Heroku, there's a similar build and deploy log on fly.io. Though I have found it to be not as detailed as Heroku, it has been enough to surface any config errors and correct them, so keep an eye on it as it'll surface any obvious issues.

    Once your deploy is working, you likely wont need to change anything for a little while, so, if you're hosting your code on Github, you can setup an action to build and deploy on a successful build.

    An example GitHub action to build and deploy a Hanami 2.0 to fly.io

    ]]>
    deploying-a-hanami-20-app-to-flyio Sun, 22 Jan 2023 06:29:33 +0000
    Managing dotfiles. It's not often that I get a new computer, but on the odd occasion that I do, I like to have all of my config prepared and ready to copy over!

    To achieve this, I am using chezmoi and GitHub to keep an up to date snapshot of my dotfiles. My previous tool of choice for managing dotfiles was rcm, but chezmoi offers things like password manager integration, scripts, and templates to customise dotfiles based on the machine I am setting up, making it just that little bit more useful.

    The initial setup of chezmoi is super straightforward, just:

    chezmoi init
    chezmoi add ~/.my-first-file
    
    chezmoi cd
    # follow your usual git workflow to add a remote and push
    

    Then, to pull down and apply your dotfiles on another machine, run:

    chezmoi init --apply $github_username
    

    From here, the workflow of adding and updating files is essentially: - Edit the source file on your machine - Then, chezmoi add ~/.file to commit and push to GitHub

    The chezmoi FAQ lists a couple of other ways you can keep a file in sync, including chezmoi edit and chezmoi merge, but I have found add to be the simplest.

    Chezmoi also makes it simple to run scripts when you run chezmoi apply.

    You can decide whether a script is run_once_ when you first run chezmoi apply, or run_onchange_, which will run every time, provided the file has changed.

    The scripts I have at the time of writing are:

    • run_once_00_install-xcode-devtools — Does what it says on the tin, installs Xcode's devtools
    • run_once_01_install_homebrew — Installs Homebrew if it's not already installed
    • run_onchange_after_brew-bundle — To run brew bundle whenever the Brewfile changes
    • run_onchange_after_configure-macos — To configure a bunch of macOS and LaunchBar defaults.

    Having a look through the chezmoi docs, you'll see there's a bunch more you can configure to meet your specific requirements, but hopefully this has provided a brief insight in to what is possible, and how easy it is to get started with a simple setup.

    ]]>
    managing-dotfiles Sun, 22 Jan 2023 06:20:43 +0000
    Naming things is ~hard~ fun Like most people*, I like to name the various devices in the house after a theme. For the longest time, my devices were unnamed, until I moved to Apple's ecosystem and picked up my first external SSD for time machine.

    My chosen theme was the Metal Gear series, so naturally, the drive was named Solid Snake, and my MacBook was Roy Campbell. Fast forward a couple years and now the lineup looks like:

    • MacBook Pro — Zero
    • AirPods — Sigint
    • iPad — Shalashaska
    • iPhone — Fortune
    • Watch — Volgin
    • HomePod mini — Quiet
    • TV — Otacon
    • Wifi — Outer Haven
    • And then I have a room light and a lamp named Olga and Sunny respectively :)
    • ... as well as a previous iPhone and AirPods pairing of Ground Control and Major Tom (which were the only ones to break the theme).

    The only annoying thing is that Air Drop shows the device name as a destination (which makes sense), but doesn't show who owns the device. A solution to this would be to leave everything as "Daniel's Whatever " — but where is the fun in that.

    *computer nerds

    ]]>
    naming-things-is-hard-fun Thu, 05 Jan 2023 05:54:15 +0000