information overload

by sebastian de deyne

Tabular numbers

14 Aug 2023

One of my favorite underrated (and underused!) CSS properties is font-variant-numeric: tabular-nums.

Tabular numbers are monospaced, which keeps their sizes consistent and keeps numbers with the same amount of digits aligned.

There are two common cases that warrant tabular numbers: tabular data and moving numbers.

Read more

Information Overload newsletter

I occasionally send out a dispatch with personal stories, things I'm working on, and interesting links I come across.

Only for occasional updates. No tracking.

Project management advice from Dune

7 Aug 2023

Apparently Frank Herbert’s Dune can teach us lessons on product management:

Arrakis teaches the attitude of the knife - chopping off what’s incomplete and saying: “Now, it’s complete because it’s ended here.”

(I haven’t read the book yet, but would love to one day!)

Mohamed Said on the synergy between PHP & Go

2 Aug 2023 via themsaid.com

I enjoyed Mohamed’s post on using PHP and Go to have the best of both worlds.

By employing a polyglot architecture, we get the best of both worlds. PHP provides the development speed required to compete in a hyper-growth market, while Go provides more efficient resource utilization.

Another good quote from the introduction of his PHP to Go course:

PHP may be slow and memory hungry when compared to a compiled language, but that’s not a result of a bad design.

It’s like this by design because of all the choices it makes on your behalf to conceal complexity.

I also recommend his post on Twitter about the business decisions behind cutting costs on infrastructure.

Granular events

26 Jul 2023

When building a CRUD interface in an event sourced system, you’ll come across the dilemma of how granular your events should be. Should you have a large PostUpdated event, or granular TitleUpdated, ContentUpdated, and AuthorUpdated events?

Read more

Rachel Andrew: "Stop treating all of your content as if it were news"

21 Jul 2023 via rachelandrew.co.uk

Personal websites are often blogs these days: a chronological stream of thoughts, news, and articles. However, some content is worth more than a post stuck and lost in time.

If I need to publish content about an emerging API, I need a couple of things. I need reference documentation so that people who want to try it out understand how to use it. This reference is evergreen content, and I will update it as the API changes. It is helpful to have, right up front, information about the last time we updated the content and the version of the spec, or browser to use for testing. I also want to let people know that we’ve shipped this experiment, so I need a news post pointing to my reference material, explaining that this thing is here, and asking people to try it out and give us some feedback. I will not update the news post; what I might do, however, is write another news post when the spec and implementation changes to let people know the progress. These news posts are my paper trail.

Food for thought for my own site. I have a bunch of old articles I wish were more discoverable as pages outside of the “blog” format.

E-ink newspaper artwork

19 Jul 2023 via projecteink.com

What a lovely project! Project E-Ink builds a large e-ink display that displays the front page of the newspaper.

{.short}

I have a strong attraction towards e-ink. I think it’s because despite being state of the art technology, e-ink doesn’t feel “digital”. In the case of this display: it’s there, it’s connected, but it’s static. It’s up to date but doesn’t grab your attention.

Beware of PHPUnit data providers with heavy setup methods

17 Jul 2023

Data providers can be a perfect fit to assert a lot of expectations without writing a full test for each.

This makes it cheap and easy to add more test cases. For an in-depth introduction to data providers, I recommend this excellent article on the Tighten blog.

class AddTest extends TestCase
{
    /** @dataProvider values */
    public function it_adds_values(int $a, int $b, int $result): void
    {
        $this->assertEquals($result, add($a, $b));
    }

    public function values(): array
    {
        return [
            [1, 1, 2],
            [1, 2, 3],
            [5, 5, 10],
            // …
        ];
    }
}

Data providers run setUp for each value. If you need a clean slate for every test, there’s no way around this. If you don’t, data providers make your tests slower than they need to be.

Consider a heavier integration test that migrate & seeds the database in setUp().

class MyTest extends TestCase
{
    public function setUp(): void
    {
        parent::setUp();

        // Migrate and seed database values…
    }

    /** @dataProvider values */
    public function it_does_something(string $value): void
    {
      // …
    }

    public function values(): array
    {
        return [ /* … */ ];
    }
}

Each case in values() will re-seed the database. If this isn’t needed, you’re better off looping over the values yourself.

class MyTest extends TestCase
{
    public function setUp(): void
    {
        parent::setUp();

        // Do some heavy lifting…
    }

    public function it_does_something(): void
    {
      $values = [ /* … */ ];

      foreach ($this->value() as $value) {
          // …
      }
    }

    public function values(): array
    {
        return [ /* … */ ];
    }
}

We recently updated a few tests in a project we’re working on, and it almost doubled the speed!

With a data provider:

Time: 00:08.517, Memory: 92.50 MB
OK (43 tests, 43 assertions)

In a loop:

Time: 00:04.448, Memory: 70.14 MB
OK (1 test, 43 assertions)