13 May 2014
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.
28 Apr 2014
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.
31 Oct 2013
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.
08 Oct 2013
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.
27 Jan 2013
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
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]