Learning How to Learn Ruby

In September, amid a torrent of people asking how I had enough money to take four months off work (low expenses, and saving in a way you imagine Smaug might) I finally picked up a new full time gig at Ottawa's tech darling Shopify. This isn't to say that my game is dead, it is simply being worked on the way most indie games are -- at the cost of sleep and in between the gig where I'm actually making money.

Getting in at Shopify in many ways seemed like an incredible misunderstanding. I've never written much of anything in Ruby, or Rails, which Shopify uses for most things, my previous programming jobs didn't have processes as much as they did openings to give someone else a rough time and I had become quite used to a very solitary development cycle. Problems I had needed to be solved on my own, no matter the time commitment because no one was going to help me. All of what I knew about being a dev abruptly u-turned. Not a bad thing, but there was some culture shock. Still is sometimes.

It was the end of October before I really felt like I was spinning my wheels. I had thought I was a fairly smart, experienced programmer, but the tens of thousands of lines of code I had to parse through was starting to feel nearly unsurmountable. I didn't have great debugging strategies (I'm still not sure I do, but I'm getting better), so tracing code was giving me an aneurysm, and every step had me feeling more bogged down and frankly stupider. My life in statically typed languages make Ruby seem like it was doing things it absolutely should no be able to, Ruby is a pliable language and the best way (if it even exists) can be challenging to tease out. The lingo, containing phrases like 'duck typing' wasn't helping. My team lead was encouraging me to ask for more help, which I was grudgingly doing more regularly, but I was asking the wrong questions and I didn't feel like I was learning much more than 'how to solve this particular issue in front of me', so the next issue would hit equally hard. I had run the Rails tutorial, but on finishing it didn't seem as though I had picked up much more than 'how to build a microblogging platform', and in general I didn't feel creative or analytic, I felt like I was following directions. I am not known for my great love of following directions.

So, I was lucky when serendipity struck and I came across this article written by Barbara Oakley about the upcoming session of her "Learning How to Learn" course on Coursera. I immediately signed up. In general, I like having an online course on the go to keep my desire to get a graduate degree mostly in check. I wasn't expecting too much stress from this one which was going to be necessary to avoid contributing to the massive burn-out I was already feeling. In fact, it all worked out well, because this course is actually fabulous, really interesting material, and wasn't overwhelming in its weekly workload I highly recommend it to anyone trying to learn something new, be it arts or science, school, or extracurricular. You could easily do it parallel to existing work or school commitments.

The rest of this post is going to talk about how using Learning How to Learn as a template I've righted the S. S. Information Overload, and feel more in control of getting the information I need from out there inside my head. Though I still am a Ruby and Rails novice, I have a structured plan for improving rather than simply running around with my hair on fire. As a general disclaimer though, I am approaching learning Rails as an experienced developer, though one coming from a different perspective, things that I apply here might be useful if you are a completely new dev, but that's not really the audience I'm aiming at here. I think this is more for people switching programming paradigms.

The first week of Learning How to Learn probably explains why as a prolific daydreamer I was a smart child that got dumb, as it illustrates the difference between diffuse learning and focused learning and points out that both of these are equally important to absorbing new things. Focused learning being probably what you actually think of when you think of learning, sitting in one place, reading material, quizzing yourself on it, but generally keeping your attention singularly on the one thing you are trying to learn. Diffuse mode learning is why you have your best ideas in the shower or as you are drifting off to sleep, and is what happens when you stop drilling the material and start letting it roll around in your head. It's easy to discount the diffuse despite its importance, and really hard to find percolation time when you're sitting in an office, going for a five minute wander to let the pile of info you've just filled yourself with really seep into your brain can look and feel to both yourself and others like you're not really giving this learning thing your all. I've been working a strategic extended tea break into my mornings and afternoons, to just walk around the office, let my head clear and try to let my understanding deepen, I'm now that weird guy on the bus without headphones in and not reading to try and take advantage of the designated daydreaming time. Though I will point out, and the teachers of the course also mention this, the diffuse mode isn't going to help you if you don't put in the focus time -- read the issue, take a stab at it, understand why your fix probably didn't work, then let it sit. Your subconscious isn't going to do the work if it doesn't have something to chew on, but of course remember the flip side, if you keep obsessing over the issue you aren't going to make progress either. I'm still working on striking a good balance here.

Another concept that can be hard to apply in an office is the idea of focusing on the process over the product. Which is to say, not setting study goals such as "resolve this issue", and instead aiming to "spend an hour devoted to nothing but this before taking a short break". In particular, Learning How to Learn espouses the Pomodoro technique, which I use a modified, and less formal version of to keep me on task. On the job, you obviously need to deliver results, the issues in your queue seem like better goals than simply making a very concerted effort on something, but the effectiveness of process over project comes from making learning seem less overwhelming, you may not be able to solve that issue in a day -- that's just reality checking in, so you light up some pain points in the brain and are reluctant to return to the issue, but anyone can spend an hour really digging into a problem. I've been using two strategies to merge this concept into my work, first revising my own vocabulary, so my daily agenda uses more process based language (I'm not going to "finish that blog post", I'm going to "spend 45 minutes revising the latest draft"), and using the gaps between time blocks to evaluate if I'm really using my time effectively -- I just spent an hour tracing through this tricky piece of code, is it now time for me to look at it another way, or even ask someone for some help? Usually, I'll have several blocks in a day set aside for the same bug, and if I go a little over on a time block that's fine, but setting the goal as working instead of finishing makes early stage learning far less stressful, and it's easiest to learn when your brain isn't buzzing with anxiety.

Info from the second week helped to differentiate both the advantages and the disadvantages when it comes to learning Rails after years experience in the statically typed C++-like languages, as it focused on Chunking, which illustrates the concept of Einstellung which I'll get to in a minute. When learning, you often pick up many small bits and pieces, for example syntax in programming when you are just starting can be difficult, remembering how to structure an if statement can be frustrating, but programming eventually gets easier as some concepts bunch together with others in what is called a 'chunk' to form a broader picture. I don't think about syntax when I'm coding anymore, it just sort of comes to me. Learning is all about taking these puzzle piece like chunks and assembling them as a cohesive complete understanding. So, as an experienced programmer, many of these software development chunks were already more or less in place, I have a very clear understanding of object oriented programming, inheritance, and control structures, thus generally have sound knowledge of what I should be able to do in a given code project. The problem comes from another concept presented in this section called Einstellung, the tendency to get stuck in a rut of doing things a particular way because that's what you're used to rather than digging to find a better way.

Ruby, and Rails both contain a certain level of 'magic' or methods that anticipate common tasks and just do the thing you want them to do, it's very idiomatic. As such, there are many elegant solutions to problems that those of us coming from other languages don't know that we don't know. Getting started I took the time out to code several things by hand that already exist in Ruby because I simply didn't know the language well enough to realize there was a better way. I was converting strings to arrays in order to reverse them, which is how you would do it in C#. Einstellung had me pretty positive that I knew how to solve the problems presented to me, and so I didn't even try to find a better, more Ruby way. It similarly made the new code I was being introduced to harder to read -- concepts that I clearly understand were invisible in the application code because they were expressed in a completely different way than I was used to.

The best way around this kind of rut for me came up around week three, and four in the course which cover procrastination and memory, and sort of a potpourri of learning strategies and information respectively. These chapters focus more on concrete strategies you can use, given the theory they present in the first few weeks.

One thing these chapters really emphasize is testing yourself. Originally I thought that's what role my work issues should be playing, but at this stage testing actually ended up being more fundamental. Understanding Ruby idioms and customs and writing code that way, sometimes by searching for examples in work code and using it as a template. The problem was that working on issues at work was reinforcing un-Rubylike behaviours, because if I couldn't find a good sample to imitate because I didn't know what I was really looking for I fell back to trying to solve problems the way I would in C# using Ruby syntax -- all without fully being able to read what was going on in the first place, less a test and more dropping into an exam I hadn't studied for.

The most effective early stage testing came in the form of drilling the beginner modules and magic tricks on Ruby Monks, and Codecademy (unfortunately now requires payments for several modules), giving a short feedback loop and making sure I wasn't letting what I thought I knew stand in the way of picking up the stuff I didn't actually know. Testing after finishing the online code school approach became work on a side project, which wasn't as short a feedback loop, but at least stopped me from fooling myself into thinking I knew something I didn't. I had made the mistake of following the Rails tutorial too closely, without really testing myself and when I set off in my own direction suddenly I didn't have quite the skills I thought I had.

Rote memorization doesn't give you understanding, but you'll be hard pressed to get the message if you still can't really read, so taking the time to really drill and test on core concepts sometimes over and over again isn't a waste of your time. I didn't make flash cards, but the focused learning from RubyMonks was critical in getting a firm footing to start digging into the more esoteric Ruby concepts. Even if it feels trivially easy in places. Like moving from learning French to learning Spanish, even if you can see more or less what's going on it's never a bad thing to take the time to really get into the details of the difference.

Once I had really developed the vocabulary, I began to interleave high level concepts about the Ruby way and not just the Ruby language in with the low level application. I would read the parts of the highly recommended Practical Object Oriented Design in Ruby, and listen to talks on ConFreaks, then switch to more down in the dirt topics like doing some Project Euler challenges or working on some side projects -- rewriting Ex Libris in Rails, and rewriting my HTML5 game project in Opal. Trying to avoid the temptation to work for extremely long sessions without breaks, and remembering that spaced repetition (doing a little every day) is how you learn new stuff, not cramming. Just like for exams. My true nemesis.

In general, I would recommend everyone take this course. It would have been helpful to me in university, high school, and elementary school, I probably could have applied it to extracurriculars that I've worked on and side projects. I can't even begin to cover all of the general tips they provided -- such as the importance of sleep, and how to use your 'zombies' or subconscious habits to beat procrastination while still keeping this blog-post length. Learning when you think you already know something can be tough, it's hard to get a handle on where to fill the gaps without boring yourself to tears with the trivialities, but I think a strong comprehension of what learning is and how to do it can make it less of a strain, and get that info into your brain not just more quickly, but more deeply.