• My AI appetites

    I’d say my overall attitude to using AI for software engineering is still in the “cautious” phase (it gives me the ick when people say bullish and bearish), but more and more I am integrating it into my day-to-day work and responsibilities at Discourse.

    In this article, I will go into some things that I am finding AI tooling useful for, and some areas where I wish it would improve, or that I am still finding my feet on. I will also cover how the prevalence of AI affects me as a tech lead and how it impacts our workflows on a product development team. So we are on the same page, I spent most of my time writing Ruby, Rails, JavaScript, Ember, and SQL code.

    Read more...

  • Cleaning up this blog with AI

    It has been several years since I wrote a post on this blog. Part of this is not really feeling like something I have worth articulating here (though that is changing a little lately), but a bigger part is that it felt like a huge amount of work to get this blog into a state where I didn’t feel like it was full of outdated articles and junk metadata. Something a little more current.

    Well, we now have a tool that all of us can use to help ease this kind of menial work: AI. So, using ChatGPT, I cleaned house and wrote this article to cover how I did it.

    Read more...

  • Six weeks at Discourse

    I meant to make a post about this when I started, but I have now been working at Discourse as a Software Engineer for six weeks!

    discourse logo

    The best things about working at Discourse are:

    • The team (39 people and growing, largest I have ever worked on) is fully remote and distributed across every continent! (well, except Antarctica)
    • Asynchronous work culture has been the core of the company since its inception. Discourse bleeds asynchronously!
    • The team is full of ridiculously talented people who are generous with their knowledge. Everyone is a stellar written communicator.
    • The codebase is fully open-source and is varied. On any day I can be working on the huge core product, a plugin, a theme component, or contributing to an open-source project Discourse uses.
    • There is a lot of reading and a lot of writing, which is kind of a thing of mine.
    • Everyone is treated like grown-ups, and trusted to do their work on their own schedule.
    • How much more time do you have? I can keep listing things!

    I am over the moon with this job and still pinch myself each day when I think about where I work and who I work with. 🌟

    look at us

  • CSV header converters in Ruby

    The CSV library in the Ruby stdlib is a really great and easy to use one, and I’ve often used it for data migrations and imports. When importing data I often find it useful to validate the headers of the imported CSV, to ensure that valid columns are provided. Some users may provide columns in different cases to what you expect or with different punctuation (including spaces etc.). To normalize the headers when parsing a CSV, you can use an option passed to new (other methods such a parse, read, and foreach accept the same options) called header_converters. Here is a simple example of how you can convert the headers of the parsed CSV to lowercase:

    Ruby
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    
    ###
    # Source CSV looks like:
    #
    # First name,last Name,Email
    # Abraham,Lincoln,alincoln@gmail.com
    # George,Washington,gwashington@outlook.com
    
    downcase_converter = lambda { |header| header.downcase }
    parsed_csv = CSV.parse('/path/to/file.csv', headers: true, header_converters: downcase_converter)
    parsed_csv.each do |row|
      puts row['first name']
    
      # => Abraham
      # => George
    end
    

    Simple as that. You can do anything to the headers here. There are also a couple of built in header converters (:downcase and :symbol) that can be used, and an array can be passed as an argument, not just one converter. Converters can also be used for cells in the CSV rows as well, not just headers. The documentation for the Ruby CSV class is quite clear and helpful, take a look to see all the other myriad options for reading and writing CSVs in Ruby.

    Originally, I found this solution and tweaked it a bit from this StackOverflow answer - https://stackoverflow.com/questions/48894679/converting-csv-headers-to-be-case-insensitive-in-ruby

  • Per-page background images using prawn and Ruby

    Prawn is an excellent PDF generation library for ruby, and we use it for all our PDF needs at work (Webbernet at time of writing). Their manual is some of the best documentation I have read. Recently, I needed to set a different background image on every page of a PDF I was generating.

    Read more...

  • ImageMagick unable to load module error on AWS Lambda

    This may no longer be relevant in 2025, but it was critical back in 2019. Leaving it as a historical curiosity.

    Last Friday (July 2019) we started seeing an elevated error rate in our AWS Lambda function that converted single page PDFs into images using ImageMagick. We had been seeing the same error crop up randomly in around a two week period before Friday, but we were busy with other things and didn’t look too deeply into it. This was a mistake in retrospect.

    Read more...

1 / 11