A piece of Ruby code I often see in ActiveRecord code is this:

self.race = "hooman"
self.name = "Nom Nom"
self.catify!

The 2 first lines are perfectly correct, but the last one feels like the coder was either mechanical or not really sure what he was doing.

race and name are both columns in the table. As a Ruby newbie you probably once did race = "hooman" but noticed it didn’t work and said to yourself: “I won’t let this happen to me again. From now on, I’ll prepend self. whenever I’m calling a method!”

It’s like people that wear a baseball cap all the time, outside, inside, when browsing the tubes, when eating and at their wedding. It’s just not polite!

Be Selfish of self, Ruby Wants You to!

The 2 following lines are the same for Ruby, whenever, wherever:

call_me "Bob"
self.call_me "Bob"

always, all the time, no question!

The tricky part is with assignment. The reason behind this is that Ruby allows the sweet sweet sweet syntactical sugar of calling a method that ends with = like an assignment.

life.truthiness = true
# is a super sweet version of:
life.truthiness=(true)

But that comes with a downside. Ruby also uses the something = value form for local variable assignment. See the clash here. That is when, and only when you are required to put a gentle self. in front.

The syntactical sugar of calling a message=() method like an assignment is only recognized by the Ruby parser when a receiver is in front:

receiver.message = value

On the other hand, this is a local value assignment:

message = value

Code, Or it Didn’t Happen

All that magic is handled by the famously magic and complex Ruby parser:

truthiness = true
# parse tree
s(:lasgn, :truthiness, s(:true))
self.truthiness = true
# parse tree
s(:attrasgn, s(:self), :truthiness=, s(:array, s(:true)))