Notes on Interactors

Interactor is a sweet little gem that you can mix in to the classes implementing your business logic to expose a common interface:
class MyInteractor
  include Interactor

context =
=> #<Interactor::Context>
Following a conventional ‘service object’ pattern, a class method ‘call’ is defined for you. This returns a ‘context’ object, which we can query like so:
  => true
  => false
You can think of ‘context’ as representing the life of the interaction – and, as we shall see, the lifespan of an interaction can be greater than that of a single interactor.
As our interactor has no behaviour, this context has had no reason to report a failure. Let’s give it some behaviour by overriding the instance method `call` to cause the interactor to fail if it is given a number that is not even.
class MyInteractor
  include Interactor
  def call!(error: context.value.to_s + ‘ is not an even number!’) if context.value.odd?
context = 3)
  => false
context = 4)
  => true
One thing I’ve learned from playing with interactors so far is that calling on the `context` object all over your class quickly gets confusing. The convention I’ve adopted is to limit access to values on `context` to the `before` hook provided by interactor (alternatively you could override initialize, but using `before` feels a little more interactor-y):
class MyInteractor
  include Interactor
  before do
    @value = context.value
  attr_reader :value
`Before` is run prior to the instance method `call`.
There’s a second problem with `context`, however, which is that as it is a subclass of OpenStruct you’re open to a lot of NilClass errors throughout your interactor. Misspell ‘value’ when calling `context.value`, for example, and rather than getting an easy-to-fix unknown variable error you’ll get nil silently flowing through your domain layer (in this case blowing up on `odd?`).
There are some extensions out there that provide some quasi-type-safety for your interactors, but a quick way of ensuring that the attributes you need in the `before` block are available is to convert the context to a hash and use fetch to assert the presence of the desired attributes:
  before do
    attributes = context.to_h
    @value = attributes.fetch(:value)
This way, you’ll get a KeyError if a parameter is missing. You can also easily provide a default as the second argument to `fetch`.
Interactors get more interesting when you start chaining them together with `Interactor::Organizer`.  An organizer allows you to quickly compose interactors into novel sequences without having to manually wire them together. With an organizer, interactors are threaded through with a single ‘context’ object and the failure of an interactor triggers the ‘rollback’ method on those preceding it.
There are some criticisms of the Interactor gem out there:
  1. The ‘context’ variable is a glorified global variable.  The way the interactor gem encourages you to access parameters through the `context` object is potentially open to abuse. I haven’t settled on using the `before` block as a kind of constructor but it seems like some convention such as this would mitigate this danger. Notably Rack uses a very similar pattern to `context`, allowing you to pass a single “env” hash through a stack of Rack middleware.
  2. Failures are silent. Interactor doesn’t catch your errors, so I’m not sure what this criticism is about.
  3. Class names are verbs. Interactor encourages you to follow the service object pattern of encapsulating actions within classes that are named something like CreateUser or GenerateImage. This naming convention doesn’t cleave entirely to Rails’ concept of a resource, and so can be confusing. However, I don’t think this convention was ever supposed to determine the public interface of your domain layer. You could, if you choose, hide all invocations of ‘call’ behind meaningfully named methods defined on your models. So for example, you might have a `user.upgrade_account` method that is in fact implemented with a series of interactors.
Notes on Interactors

What’s next?

Just over four months ago I crash-landed back in England after 3 years abroad. I went straight from the airport to Makers Academy to attend the graduation of the August cohort and, 3 days later, was starting out a junior myself.

The challenges of abruptly ending one life to dive headlong into another have, for me, prompted a period of deep introspection. The reason I mention this is as a note to incoming students: starting out as a struggling novice at something you really want to be good at, and having to deal with all the (mostly self-directed) negativity inevitably arising from that, is a great opportunity to challenge negative thought processes in all areas of your life.*

Or, as Lao Tzu wrote a long time ago:

Always we hope
someone else has the answer,
some other place will be better,
some other time,
it will turn out.

This is it.

No one else has the answer,
no other place will be better,
and it has already turned out.

At the center of your being,
you have the answer:
you know who you are and
you know what you want.

There is no need to run outside
for better seeing,
nor to peer from a window.
Rather abide at the center of your being:
for the more you leave it,
the less you learn.

Search your heart and see
the way to do is to be.

Abide at the center of your being.

Anyway, that’s the past. Happily from next Monday I will be joining the coaching team at Makers! It is a logical move for me, given my background in education, and I am very excited. Makers is a company run by some of the most talented and forward-thinking people I have ever met.

I plan to use this blog to trial some ideas I have about the best ways of coaching students in test driven development so stay tuned if you’re interested in that.

* I recommend John Hargrave’s (free) book Mind Hacking for a techy perspective on how you might go about this.

What’s next?

Reflections: Context Switching

My time as a student at Makers Academy wrapped up over a week ago now, but I was invited to come back as an “Alumni Helper” and coach the new cohort of juniors. Before Makers I was a teacher, so it’s been a natural and enjoyable reversion to form.

I’ve been thinking recently about the idea of “context switching”. In programming, context switching is when you change from one language to another. This might happen because different projects are best written in different languages, or because you segue from one part of the stack to another.

“Language interference”, the accidental use of syntax or conventions of one language when writing another, makes context switching difficult. In my previous life as a teacher, I taught elementary-age children whose first language was Korean. Their struggle with language interference was constant, commonly manifesting as inappropriate discourse indicators. When pausing for thought, exclaiming, or about to say something, they would often make very Korean sounding utterances.

Just as with bad style, misnaming, or unnecessary complexity, context switching contributes to mental dissonance. It’s jarring to have to jump from one language to another. So programmers generally try to minimize context switching by keeping the language consistent across the stack, or at least organizing blocks of work so as not to be straddling the language-fault-lines in the codebase. Context switching is also talked about as a kind of “design smell” – indicative of code that’s breaking encapsulation.

At the same time, sometimes we have to change languages and so we might call “context switching” a skill, a measure of how readily someone can readjust to working at a different point in the codebase or in a different language.

More broadly, being able to “context switch” from focusing for hours on a few dozen lines of code to scrumming with others in the team is vitally important. Many times over the past few months I have found myself struggling to go back to being my normal sociable self after a long stretch of focus.

At Makers, pair programming helps with keeping the work within a social context. And fortunately there is Dana, the party creator, yogi, guru, therapist, and broad-smiling face of Makers Academy. Through her yoga classes in particular I have learned the discipline of pulling myself out of one frame of mind to be immersed in another.

Reflections: Context Switching

Reflections: Final Project

The final project, weeks 10 and 11 at makers, whipped by. My team was made up of Danielle, Gus, Charlie, India, and myself:

The team with clients, Tom and Amar, on day 1 of final project weeks.
Here’s the team with clients, Tom and Amar, on day 1 of final project weeks.

In the past few months Makers have been inviting external clients, usually charities, to pitch ideas at the jamboree in Week 9. Charities were selected this time around too: the Snow Angels group, for example, worked with a Sussex village charity to automate the organization of support for elderly people during times of adverse weather.

My team’s project, though, came from Tom and Amar, two ideators local to Shoreditch. “I Am Me” is born of the frustration of spending Saturday mornings scanning TimeOut and similar sites for suggestions of what to do on the weekend. Though such sites have a lot of content, it’s presented within a cluttered interface and without regard to the particular user’s interests. To boil it down, “I Am Me” is an event discovery website that has the form of a calendar. My team and I had some concerns going into the project: which features could we fulfill on in the two weeks available? Should we stick to the design brief or experiment?

In the end, we turned out a product that we could all be proud of. Users of the site can browse and create events with a visually appealing UI, and we even implemented some event-discovery, albeit of a primitive kind. Our presentation at the graduation event on got a good reaction.

As this post is titled ‘Reflections’, here are my takeaways from the project:

  • We did a good job of getting it clear in our heads from Day 1 what we were designing and what kind of user it was for. We didn’t think so deeply about the flow of the user’s experience through the site. Storyboards would have helped in this regard.
  • Use technical language carefully; make sure everyone is on the same page. People have different assumptions about what certain design decisions would entail. It always helps to have people rephrase what they mean, or think they mean.
  • Never Rails scaffold! Bad Things will ensue.

There were many highlights. I was blessed again with a team of fun and talented people from whom I learned a lot.

Reflections: Final Project

The UN Influx Hackerthon


The weekend of Feb 21/22 I rather recklessly signed up for a hackerthon called “UN Influx”, which was organized by a charity, the Influx Trust. ‘Reckless’ because I was coming out of a week’s introduction to Ruby on Rails, a web framework, and about to go into the final project of my time at Maker’s.

The problem statement was this: “How can digital innovation help the UN and the public work together more effectively?” Soon after arriving at the venue, a colourful workspace across the road from Tower of London, I met Toby Beresford, who offered to let me use his “gamification platform” for any project I could think of. I pitched an idea that I thought could realistically be built in 48 hours and fortunately, found a great team.

Irina, a designer, was the first one to join the team. She had a lot of ideas about how to present on the front end. She also managed to both attend a hackerthon and move house in one weekend. Remarkable.

There was a moment after the round of pitching on the Friday, when “ideas” people (who I had somehow become) were supposed to gather a team, when I was about to give up. Then Sandra, frontend developer, offered to do the frontend and ended up doing so some technology (Meteor) she hadn’t used before. She’s also travelled to over 40 countries and introduced me to BDD (“beer driven development”).

Ozo, a programmer originating from Nigeria, doubled as architect and visionary. He very generously agreed to using my language of choice, node.js, above any he is familiar with and also put more thought than anyone else over the weekend into what we were building, why we were building it, who it as for, and how we should pitch it.

Our project, UN Frontliners, a platform for volunteers to tell their stories of working in the field, was given the “hearts” prize by a panel of judged which included a former UN Deputy Secretary General. Thanks to my team and some of the amazing mentors in attendance, I learned a lot at the UN Influx hackerthon and had a great experience. UN Influx are planning to hold another in Autumn and I recommend attending to any fellow junior devs out there.


Here’s the team with prizes.

The UN Influx Hackerthon

Week 8: Makerthon

Week 8 was unforgettable.

It began with a talk by Charles Davies, CTO of TomTom, who condensed some of his immense experience in the tech sector into manageable drops of wisdom: read a lot, keep it simple, and hire the best even if you can’t afford them. TomTom’s revenue runs close to a billion euros, but they question was still put to him: Why buy the kind of navigation utility that TomTom sell when a modern smartphone can do all the same things and more?

His answer touched on a key concept of this week: user stories. User stories are 3-line narratives used by developers to evaluate whether a proposed feature is worth the time required to implement it. I’ll come back to them in a moment.

Time was precious this week as it was the week of the Makerthon. The Makerthon is a mini-team-based project, a practice run for the final projects. My team’s project, dreamed up by the very talented Jacob Mitchinson, was to create a bot that sits in the Makers Academy slack channel (slack is a messaging program we use to communicate) and answers students’ questions about lecture times, talks, course material, etc., basically anything we could implement in time.

So a real user story from our project was: As a student at Makers, when there is a lunchtime talk, I want to be reminded of it in advance. User stories might seem so short as to be trivial, but their importance is in being public narratives around which to discuss whether a proposed feature satisfied a real need. They’re a working hypothesis rather than a panacea for the problem of making something people want.

The Makerbot ended up doing a lot of things we hadn’t originally planned: it can tell you knock knock jokes, where to go for lunch in Shoreditch , and even the answer to “What is the average flight velocity of an unladen swallow?”. Massive thanks to my team: Jin, Danielle, Clint, and Jacob for making the week so much fun.

Week 8: Makerthon

Blocking vs Non-Blocking Processes

Blocking Processes

Imagine a teacher wants to test his students’ math ability. He gets them to stand in a line and he starts at the top, asking the first student: “What is 8 * 9?” The student replies with the correct answer almost immediately and can sit down. Things are going well. Except the teacher now asks a really difficult question to the next student and she has think for a whole minute. Meanwhile, all remaining students are idly waiting in line. Eventually the teacher gets to the end of the line, but the math test took up the whole class.

This is how blocking processes work.

Non-Blocking Processes

A different teacher conducts her math tests like this: She lines up the students, quickly moves down the line giving each a card with the problem to be solved, and she then stands by the whiteboard ready to write down their answers. The students are now working on their problems simultaneously and nobody is idle.

This seems like a very fast and effective way of conducting a math test and things are going well. Except these students, though brilliant at math, have zero common sense (much like computer programs). They solve their problems but then don’t know to report their answers to the teacher. Fortunately, the teacher foresaw this and wrote what to do on the back of the card. After completing their problems, the students turn over their cards and follow the instructions to move to the board and tell the teacher the answer. In programming this secondary instruction is called a “callback”.

Though this “non-blocking” style is a little more complicated than the previous “blocking” style, the math test has been completed in a fraction of the time and the class can get on with doing something else. Great, right? No wonder Twitter switched over from Ruby, a blocking language, to Node, non-blocking.

Okay this time, imagine a slightly different scenario. The class is studying Japanese and wants to learn the language for days of the week. The teacher, however, doesn’t speak Japanese and so instructs the students to look up the words in their dictionaries. To speed up the process, she delegates each day, Monday through Sunday, to a different student. Their secondary, “callback”, instruction is to move to the board and report the answer to the teacher.

Here we hit a snag: some students are faster with the dictionary than others. In fact, the student looking up “Friday” returns to the board first and his answers gets written down first. In the end the class has a list of seven Japanese words but no idea which of the days of the week each corresponds to. Clearly the “callback” instruction to the students was inadequate: they should, perhaps, have been told to report the English word given to them along with the Japanese translation.

I hope this elaborate metaphor has given you some insight into the relative merits of blocking and non-blocking processes. =)

Blocking vs Non-Blocking Processes