• The REPL: Issue 89 - January 2022

    The UX on this Small Child Is Terrible

    This is pretty funny. Reminds me of Introducing JIRA Jr. Project Tracking… for kids

    In Defence of the Boring Web

    I made the exact same decisions as the author to create this very website: Markdown source, a static site generator, little javascript (in my case none), and a minimalist theme. However, I don’t think boring is a good word. My dictionary defines it as:

    not interesting; tedious: I’ve got a boring job in an office.

    Instead, I would use a word that connotes tried-and-true, simple, adequate for the job. Reliable comes to mind.

    On the Various OSS Fauna

    I didn’t know about WikiFauna. I like the idea a lot: To outline the different roles that people can take to contribute to the project. I am not sure about fauna as a term, or that calling folks elves, cyclops, fairies, gnomes is useful at all.

    Nate Berkopec does a great job in adapting the idea to OSS and correctly points out that most OSS is volunteer work: You decide your level of involvement.

    Read on →

  • Playing Evil Wordle With Unix

    It seems that nowadays everyone is playing Wordle. And for good reason. It is a lot of fun! There is an evil variant, Evil Wordle that is, well, evil:

    There’s no word set by default. Every time you guess, I look at all possible 5-letter words that would fit all your guesses, and choose the match pattern that results in the most possible words. My goal is to maximize the amount of guesses it takes to find the word.

    Let’s play with unix tools at our disposal. To be on the same playing field, I took a peek at the source in the browser, and downloaded the list of words that are part of the game dictionary:

    Read on →

  • The REPL: Issue 88 - December 2021

    Programmers Should Stop Celebrating Incompetence

    DHH is well known for kicking up a storm. I don’t always agree with him. In this case, I do. We can strive for competence and embrace newcomers to programming. Software challenge us to learn new things all the time, but that doesn’t mean that we don’t know anything.

    Against my better judgement to never look at the comment section, I glanced at some of the reaction on Twitter. A lot of the objections seem to be saying “Stop telling people they can’t look up things on the internet”. Example:

    You must have everything you need to know to do your job memorized You know, like doctors and lawyers and mechanical engineers Riiiight

    DHH didn’t say any of that. He said that you should be working to improve your knowledge in the areas that you choose, and not pretend like no one knows anything.

    Be Curious, Not Judgmental

    It is tempting to trash others work and belittle it. It can make us feel bigger, smarter, better. It is not conducive to learning and deep insight. If instead we adopt a curios mindset, the results can be quite different. The post illustrates the point well.

    How to rest well

    This post by Alex Soojung-Kim Pang reinforces my belief that rest is a competitive advantage. Being well-rested improves cognition. Downtime, and time for hobbies is important and should be prioritized. “All work” is a terrible mindset.

    Read on →

  • Gotcha using Oj to generate JSON

    Oj is a Ruby gem that bills itself as a faster way to generate JSON, mainly through the use of a C extension. I recently found it was generating unexpected results.

    I was looking through a report that one of our endpoints was generating unusually large JSON payloads. In particular, timestamps where being serialized to a very verbose (and not very useful format):

    {
      "created_at": {
        "^o": "ActiveSupport::TimeWithZone",
        "utc": {
          "^t": 1639339673.031328000
        },
        "time": null,
        "time_zone": {
          "^o": "ActiveSupport::TimeZone",
          "name": "UTC",
          "utc_offset": null,
          "tzinfo": {
            "^o": "TZInfo::DataTimezone",
            "info": {
              "^o": "TZInfo::ZoneinfoTimezoneInfo",
              "identifier": "Etc/UTC",
              "offsets": {
                "^#1": [0, {
                  "^o": "TZInfo::TimezoneOffset",
                  "utc_offset": 0,
                  "std_offset": 0,
                  "abbreviation": ":UTC",
                  "utc_total_offset": 0
                }]
              },
              "transitions": [],
              "previous_offset": {
                "^o": "TZInfo::TimezoneOffset",
                "utc_offset": 0,
                "std_offset": 0,
                "abbreviation": ":UTC",
                "utc_total_offset": 0
              },
              "transitions_index": null
            }
          }
        },
        "period": null
      }
    }
    

    I quickly saw that the controller was invoking Oj directly, and that is the root of the problem. The library has a Rails compatibility mode, that is not the default:

    ts = Time.zone.now
    
    ts.to_json
    # => "\"2021-12-12T20:10:56Z\""
    
    Oj.dump(ts)
    # => "{\"^o\":\"ActiveSupport::TimeWithZone\",\"utc\":{\"^t\":1639339856.001998000},\"time\":{\"^t\":1639339856.001998000},\"time_zone\":{\"^o\":\"ActiveSupport::TimeZone\",\"name\":\"UTC\",\"utc_offset\":null,\"tzinfo\":{\"^o\":\"TZInfo::DataTimezone\",\"info\":{\"^o\":\"TZInfo::ZoneinfoTimezoneInfo\",\"identifier\":\"Etc/UTC\",\"offsets\":{\"^#1\":[0,{\"^o\":\"TZInfo::TimezoneOffset\",\"utc_offset\":0,\"std_offset\":0,\"abbreviation\":\":UTC\",\"utc_total_offset\":0}]},\"transitions\":[],\"previous_offset\":{\"^o\":\"TZInfo::TimezoneOffset\",\"utc_offset\":0,\"std_offset\":0,\"abbreviation\":\":UTC\",\"utc_total_offset\":0},\"transitions_index\":null}}},\"period\":{\"^o\":\"TZInfo::TimezonePeriod\",\"start_transition\":null,\"end_transition\":null,\"offset\":{\"^o\":\"TZInfo::TimezoneOffset\",\"utc_offset\":0,\"std_offset\":0,\"abbreviation\":\":UTC\",\"utc_total_offset\":0},\"utc_total_offset_rational\":null}}"
    
    Oj.dump(ts, mode: :rails)
    # => "\"2021-12-12T20:10:56Z\""
    

    Adding mode: :rails to the Oj call fixed the unexpected payload size issue.

    The fact that we had a production endpoint generating unexpected JSON for months lets me know two things:

    • There is no test coverage that checks the generated JSON against a known schema
    • Consumers of this internal endpoint have no use for the timestamps that were being sent down: There is no code that recognizes that data structure.

    Read on →

  • The REPL: Issue 87 - November 2021

    A terrible schema from a clueless programmer

    A very experienced engineer tells a story about a horrible database design. The kicker is that the terrible design was hers, when she was younger and didn’t know any better.

    We’ve all been there. This is how we learn. Especially when a lot of software engineers don’t have the opportunity to be mentored and guided by more experienced engineers.

    RegexLearn

    This is a step-by-step tutorial for learning regular expressions. Well explained, plenty of examples and feels like a smooth on-ramp to regex.

    The History of Command Palettes: How Typing Commands Became The Norm Again

    So much this: Typing commands is better than clicking your mouse. Command palettes help with discoverability.

    In fact, one of my “must-have” Alfred extensions is Menu Bar Search. It adds the command-p behavior to any program, by searching the text of all the menus (using accessibility access). I use it a lot, in all sorts of programs that don’t include such functionality natively (e.g. Quickbooks, Firefox).

    One thing not mentioned is that a shell typically also stores history, which helps you discover commands you’ve already typed before. I use my history all the time and use a fuzzy finder to search through it.

    Read on →