Makers Academy Day 4
If you ask a Literature student about ‘the Self’ you’re likely to get a lengthy explanation of Self in Jungian psychology, where the consciousness and unconsciousness of a person are unified. In the below diagram of the Self, the central dot is the ego, whereas Self is both the whole and the centred dot. In other words, we have twin centres:
What on earth has this got to do with programming? Well, Ruby also has a knowledge of itself that can be used in effective ways to write code, and is described as Metaprogramming. As everyone always says everything in Ruby is an object. This matters because by proxy every piece of code you write must also therefore belong to an object.
Having encountered self a few times in my own code, I’ve had the sense that it’s been difficult to grasp exactly what’s happening under the hood of self. That crucial difference between being aware of a concept and translating that into actually being able to apply it.
Today I was working on this Bike class with my pair. We were feature testing the below report_broken method in irb before writing our Rspec unit test:
We wanted to change the status of a bike from “working” to “broken”, we did that by reassigning the status to broken for any bikes that were reported as broken. It was crucial to us that the status attribute was changed for that instance so we could then later check if it was working. When we tested this in irb we could see that the bike was created and initialized as expected to have a working status. When we the report_broken method was invoked on the instance of bike, it returned “broken”. Looking back this makes perfect sense as this what we had changed status to be. However, when we were feature testing we had thought we would get back the bike object ID number alongside its status, which we expected to be “broken” as an attribute of status. When we saw “broken” as a string we were worried that this hadn’t been stored as an attribute, although when we invoked the working? method on bike it gave us the false boolean response we had expected.
This was why we added self to line 14 of our class. Our reasoning was that self would return the object ID and its updated status, rather than just the “broken” string. In reality, we misused self because it wasn’t necessary on line 14, as the method was infact already returning what we wanted it to we had just gone about affirming our assumptions in the wrong way. Self was returning the same object as the return of that method, and so we could have just deleted it.
What we needed to have done was, after reporting the bike as broken, to check the bike instance. This would have visualised to us what we already knew must have happened, because our working? method was returning what we expected.
What I think happened with our misuse of self was that we had remembered using self as an instance method on other exercises. Where we used self to point to that object. We overused self because it tallied with something we had seen and used in a similar context previously.
There’s a long way to go before I feel fully comfortable with applying self in different contexts, that make sense in the given situation. Expect more blog posts on this topic! Thanks to Christoph for helping me explore this further :).