You Cruel, Heartless Bastards

(all that tea, actually, since leaving, i’ve become more british, vegetarian haggis exists and comes in cans)
()

Look at these people. Enjoying themselves, throwing away all that tea.

so cruel, so cruel

All I can hope is that it was Lipton. AND ONE DAY WE WILL COME FOR OUR BACK TAXES, COLONIALS.

Anyway, this might be my last week coming up to Boston, and it’s certainly my last visit of 2014, so I thought I would stay an extra day and get to wander around the city during the day-time (which I last did in February). 15 miles of walking later, my feet are regretting that decision. Still, I wandered around the tourist haunts that I last saw over a decade ago - Quincy Market, the Freedom Trail, various bits of MIT and Harvard, lots of different parts of the T (this time, I think I got a full set of colours!), along with a bizarre visit to Pret A Manger in downtown.

(it’s a bit pared-down from a UK Pret, and the Christmas Sandwich has suffered the twin heresy of being renamed the Holiday Lunch and having all the Proper British Stuffing replaced with American cornbread stuffing and turkey ‘gravy’. On the other hand, they do sell bacon mac ’n’ cheese)

Somewhere around mile 8 or 9, after wandering around an interesting five-level vintage market where the building shook constantly from the building outside (smashing several glass shelves as I was walking along!), my feet decided that they were not entirely happy with the day’s planned activities, especially seeing that I was still several miles away from where I was staying. Eventually, I made it back to the T, and had a quiet evening around Harvard Square and an Indian restaurant in Somerville.

Today, I’m back in Waltham, and for some reason, I’ve been given a suite! Not one, but two TVs! Couches, glass bricks dividing it into two rooms, and all sorts of fancy things. It’s a bit wasted on me this week, but hey, if anybody wants a party in Waltham, I appear to have a venue!

The Red Mark of Durham

(plague sign, cut down all the things, vines are evil)
()

A new experience on being a home owner; coming back to the house and finding this noticed stapled (yes, stapled) to the house:

This…was new. My favourite part of the notice is that it points to the part of city byelaws that you’re violating…but not exactly what you’ve done wrong. Plus, you have ten days to fix it after the sign is posted, but the letter that gets sent out that actually explains what’s wrong didn’t turn up for a week.

Thankfully, I was embarrassed enough that I phoned the City as soon as I found the notice, but couldn’t get through to the correct person until the next morning. Apparently, the bushes at the end of my garden were getting in the way of the recently-moved bus stop and were blocking the path. Now, I had idly planned to take a saw to various trees over Winter after the leaves were gone. But I had not ventured down to the back of the garden in a little while (I’ve been away, and hey, it’s not as if there’s anything useful down there); one brief look last Thursday made it clear that the City wasn’t really kidding; my bushes had grown wildly over the summer.

This is all a buried lede to: Ian does gardening for almost the first time ever. This involved going to Lowe’s and texting pictures of various items to people to make sure I was buying the correct thing (I almost bought a few oddities, so it was wise to check with people who had more of a clue than I did), and then getting up at the ungodly hour of 8am on a Saturday morning. It’s been a while since I did that on purpose.

I had some help, so it wasn’t just me lopping over big bits of tree. By the early afternoon, not only could I see the bus stop from the house’s windows, but I could also see into the next-door neighbour’s garden, which I don’t think was possible even when I bought the house last year. Success! Except for the piles of branches all over the garden. Anybody fancy a bonfire?

A bit of an embarrassing episode, but the pavement is now mostly clear, and no over-hanging bushes causing problems for people waiting for the bus, which is a good thing! I do really need to come up for a plan for what to do in the back garden; this year it has suffered from quite a bit of neglect, and I’d like to clear out all the spreading vines and pallets that I’ve inherited. It’ll give Bonnie room for her intended Huf Haus, obviously.

Begin The Quarter Quell!

(macarons are a tool of the capitol!)
()

I have now seen Catching Fire, despite not having seen or read the first book / film of The Hunger Games. All I can really take away from it is that I enjoyed macarons being used as a signifier of depravity, indifferent evil, and excess. That’s the moral the writers were trying to convey, I’m certain. There might have been some other bits with revolution and mockingjays, but trust me, it’s all about the macarons.

Today has not been a great day. Hopefully, November will get better.

The Monkey, Refined

(ruby, monkey-patching, refinements, metaprogram all the things)
()

Monkey-patching. It strikes fear into newcomers to Ruby, excitement and abandon in moderate Ruby developers, and sad, disgruntled sighs from the experienced developers who end up having to wade through a huge Rails codebase to find out where somebody decided to monkey-patch the mysql2 gem in a way that makes it incompatible with a Rails 4 upgrade (bonus points for hiding the patch in something like app/models/stats/nightly_stats_run/customer_roi.rb, obviously).

(bitter tears of experience here)

But hark! Ruby 2.1 is here, and may contain some salvation in the form of refinements. First, though, a refresher.

Patch that Monkey!

Monkey-patching in Ruby involves modifying code at run-time, either by extending and providing additional functionality or redefining existing code. And Ruby makes it so easy! Consider this little gem:

class String
  def all_is_love
    ‘❤’ * self.length
  end
end

This extends String with the method :all_is_love, so:

pry(main)> 'hello'.all_is_love                                              
=> "❤❤❤❤❤”

This is how large chunks of the Rails helper methods (e.g. :camelize) are implemented. And this is fine…except due to the Magic of Ruby, you can do this pretty much anywhere in your code. And you can do this as well:

class String
  def length
    2
  end
end

pry(main)> 'hello’.length                                              
=> 2

Just to give you an idea of the systemic breakdown this can create, let’s go back to our earlier method:


pry(main)> 'hello'.all_is_love
=>"❤❤”

Again, there are sometimes reasons why you have to monkey-patch and replace methods at runtime. Perhaps your database connection has some legacy weirdness that needs to be worked around and it isn’t covered by a standard gem (this is a code smell, obviously, but sometimes it has to be done). Being able to do this at-will in a large code-base, however, can easily lead to problems. Maybe you do your patch in an obscure area of the code, and a new developer writes a method that uses the expected behaviour, and then spends a day or so trying to work out why her code isn’t working correctly. Or even worse, somebody decides to write another monkey-patch on the same method, meaning that the behaviour in production becomes a Fun Race Condition That Wakes You Up At 3am depending on which one is executed by Ruby first.

The real answer is Don’t Monkey-Patch, and enforce it with hammers. But sometimes it’s not possible to avoid that monkey. Thankfully, Ruby 2 delivers a way of at least limiting the scope of patches with Refinements.


module WithAMonocle
  refine String do
    def all_is_love
      '❤' * self.length
    end
  end
end

Module#refine takes a class and a block, and in that block, you can extend or redefine to your heart’s content. But:


pry(main)> 'hello’.all_is_love                                             
NoMethodError: undefined method `all_is_love’ 
for "hello":String

Refinements need to be specifically activated with the using keyword:


using WithAMonocle
puts ‘hello’.all_is_love
=> "❤❤❤❤❤”

Okay, so far, much the same as normal monkey-patching. But the magic is that the patch only exists in that scope. So if we embed them in a Class, the refinement only exists within that class. For example:


class SplendidMonkey
  using WithAMonocle
  puts 'fff’.all_is_love
end

❤❤❤
=> nil

class UncouthMonkey
  puts 'fff’.all_is_love
end

=> NoMethodError: undefined method `all_is_love’ 
for "fff":String

The monkey-patch is restricted to the class where it is activated. As you can imagine, this is all sorts of useful - not only do you not pollute the global scope with your redefinitions or extensions, but you also make it explicit that you’re using that particular patch (and also providing a giant big clue where the patch is defined).

So, still, don’t go crazy with your monkey-patching, but, if you have to use them (and you’re running on a current Ruby 2.1.x version), consider using refinements as a way to limit their problematic features…

(however, do be aware that there are a few odd things that may bite you if you’re not paying attention. In particular:


module WithAShortMonocle
  refine String do
    HEART_LENGTH = 1
    def all_is_love
      '❤' * HEART_LENGTH
    end
  end
end

Constants and class variables within a refinement belong to the module, not the class being refined:


pry(main)> String::HEART_LENGTH
NameError: uninitialized constant 
String::HEART_LENGTH
pry(main)> WithAShortMonocle::HEART_LENGTH
=> 1

So be aware of that when adding your refinements)

Sick Raleigh

(raleigh, sick)
()

This week I seem to have spent a lot of time ill, and a lot of time in Raleigh. Good to see the Reverbnation team again during All Things Open, though it would have been better if I hadn’t been feeling quite so ill.

In other discoveries this week: pickling red onions in orange and lime juice is actually quite tasty…

buy my books
Instant Zepto.js
Scaling Node.JS (coming soon)