ciarand.me another code blog

A college student's kitchen survival kit

Since moving out on my own there have been a few pieces of kitchenware that have become indispensable to me. From making coffee in the morning to cooking dinner, these are the things that I would buy again in a heartbeat if I were starting over.

Cast-iron pan

I picked mine up at Target for around $25. Cheaper versions abound, and should be relatively easy to find at a garage sale or similar. It's been a fantastic investment, and I use it for almost every bit of cooking I do. It's easy to clean and easy to cook with, partly due to the predictable heating cycle.

Rice cooker

I'd never used a rice cooker before moving out, but one of my first roommates used his all the time. When I moved to my current apartment it was one of the first things I bought. Mine cost $40, and I don't recommend paying much more than that unless you know why you're doing so.

A $20 bag of rice lasts me close to 4 months, and it's one of the easiest parts of a meal to make. The cooker can keep it warm for ~12 hours (there's technically no upper limit as far as I'm aware, but my ex-roommate cautioned me against keeping it warm for longer than that), and you can always put it in the fridge for lunch the next day.

French press (or an aeropress)

I own and use a French press for making coffee. It's just about the easiest way of making coffee, and it's infinitely more sustainable (both economically and environmentally) than the Keurig pods.

Many coffee fanatics will claim that an AeroPress produces a better cup, but the fiddliness associated with it is not worth it to me. If getting the best brew matters to you, you can invest in both an AeroPress and a decent grinder.

Electric kettle

I've got a nondescript red electric kettle that I use for boiling water for coffee, tea, and pasta. It's not a huge part of my day, but I can't imagine living without one.

Food storage containers

I have these containers for food storage. They're glass, which means they don't bend or morph in the dishwasher. The lids have a satisfying click when attached and the base can be put in the microwave with no worries about chemicals leaking into the foods.

I don't have any real preference for a specific brand. Anything that offers tempered glass and snap lids is probably going to do a great job.

As a baseline, I only end up using about 4 or 5 of these on a regular basis. If you can find someone to split a full set with it becomes a lot more financially reasonable.

Spatula

I use this almost every time I cook. If I don't, it's because it's in the dishwasher. In fact, I'm ordering a second right now.

Cookbook

This is one of the few cookbooks I own. It's absolutely fantastic as it contains not just a set of recipes, but a set of cooking guidelines. It includes gems like making your own pesto, essentials like how to make hardboiled eggs, and important ones like how to sear a steak. This is my go-to gift for people moving out for the first time.

Wrap-up

This really is my core setup. Almost all of these things get used every day, and if I had to start my kitchen over I'd buy every one of these first.

New blog

This is a new blog! It's being run on Hugo and uses a Hugo port of the Hyde theme that I've open sourced here.

I'll post a little more about the details of the engine in the future, including how the porting process went, some problems I've encountered, and more.

"Web Development" is a big field

I've been thinking a lot about what I'd like to be doing inside this big buzzword we know as web development.

I really like writing internal tools, tests, and introducing new systems to help myself and the other developers on a team work more efficiently and effectively.

I also love the mental acrobatics that writing a scaling application requires from a developer; stuff like database normalization and writing cache-friendly application structures excites me.

Finally, I know how to write scalable CSS. I like a lot of the concepts there from a theoretical standpoint, but my experiences with designers so far have left me frustrated and unhappy. I'm positive that there are designers that are a real pleasure to work with, but I have not had that pleasure.

I guess what I actually want to do doesn't matter as much. It's a very nebulous thing. On the other hand, there's a whole set of things I now know I don't want to do.

On a related note, starting in 2014 I'll be available full time for any new development work. If you'd like to start a conversation, you can email me at me@ciarand.me.

Decoupling for Better Testing

Unless you start out with the right mindset, an application's natural progression is toward chaos, inefficiency, and disorder.

Why is tight coupling bad?

Tight coupling hurts your app in the long term. Let's use an example (the code is in PHP, but the principles are generic).

<?php # models/User.php

class User extends MyBaseClass
{
    // Snip

    public function IsAllowedOnCurrentPage()
    {
        $pageUrl = $_SERVER['PHP_SELF'];
        // Or, if you're using a framework:
        $pageUrl = Yifonyaverl::app()->url->current();

        return in_array($page, $this->allowedPages);
    }

    // Snip
}

Do you see the problem? It's prescriptive. The User model now needs to know what page the user is trying to access. A better method? Have the requesting entity (probably a controller of some sort) tell the user model what page to check against, like this:

# models/ImprovedUser.php

class ImprovedUser extends MyBaseClass
{
    // Snip

    public function IsAllowedOnUrl($url)
    {
        return in_array($page, $this->allowedPages);
    }

    // Snip
}

That all sounds well and good in theory, but why should you, the pragmatic programmer, care? Well, because you like writing testable code. How would you test the first function? You'd probably have to adjust the $_SERVER global variable before the test, something that might impact your other tests. Here's an example test case:

# tests/UserTest.php

class UserTest extends PHPUnit_Framework_TestCase
{
    // Snip

    public function TestGuestIsNotAllowedInAdminArea()
    {
        // A generic guest user
        $guest = $this->fixtures['guest'];

        // "mocking" the URL
        $_SERVER['PHP_SELF'] = 'admin.php';
        $this->assertFalse($guest->isAllowedOnCurrentPage());
    }

    // Snip
}

This is broken and wrong. Who knows what other components rely on PHP_SELF being accurate? Is your framework using it? Hopefully not, but that's not a risk you want to take. Here's a better way:

# tests/ImprovedUserTest.php

class ImprovedUserTest extends PHPUnit_Framework_TestCase
{
    // Snip

    public function TestGuesIsNotAllowedInAdminArea()
    {
        // A generic guest user
        $guest = $this->fixtures['guest'];

        // Instead of mocking, we can pass the URL in directly
        $this->assertFalse($guest->isAllowedOnUrl('admin.php'));
    }

    // Snip
}

It's actually one line shorter, and far more testable. You could use a data provider to test an entire set of pages very easily, and know full-well that the only thing you're testing is the model's method. You've isolated the method and the logic, and can rest assured that, once you've written the tests, this method will never fail you. That's a comforting feeling.

In my next post I'll go over a technique for decoupling more complex relationships using a publisher / subscriber pattern.

Using systemd template files

Arch Linux ships with systemd as the system management daemon. It's very cool, but I struggled for an embarassing amount of time with getting it to start envoy (an ssh-agent management tool). The problem I encountered was mostly due to my naïve assumption about the autocompleted service files.

Specifically, bash autocompleted

systemctl enable envoy

To:

systemctl enable envoy@service.service

I didn't really know what the "@" meant, so I assumed it was correct and ran with it. On my next restart it failed, and after some research I finally figured out why. The "@" in systemd filenames signifies that the file is a "template" file. There's a really good explanation on stackoverflow. Here's the relevant part:

The @ symbol is for special services where multiple instances can be run.

For instance, getty@.service is the service that provides text login terminals. When you press Ctrl+Alt+F2, getty@tty2.service is started, creating virtual terminal #2.

Basically, the part after the "@" and before the extension (".service" in this case) is a variable that's used inside the service file. I disabled "envoy@service.service", enabled "envoy@ssh-agent.service" and reloaded systemd. Everything's working now and I understand systemd better.

As a sidenote, I found the following commands to be really helpful in debugging problems related to systemd:

# Show a service file's details, including file location
systemctl show [service name]
# Show failed units
systemctl --failed
# Show all logs this boot (-b) related to that service file
journalctl -b | grep [service name]