Fun fact: I don’t blog for you, I blog for me.
I know. But really, case in point right here. This is not a particularly complicated concept, but it’s something that is easy to get lazy about, and something I’ve been thinking about. If I write it down, I’m more likely to follow through. So here we are.
As a new rubyist, scope is not always immediately obvious to me. What is obvious to me, is when I get an error that says something like NoMethodError: undefined method ‘[]’ for nil:NilClass
when the thing I’m calling the method on is definitely not nil
. By which I mean, of course, definitely should not be nil, but apparently is. (Because, if there’s an error, it’s a pretty safe bet that the computer is not wrong, I am).
When that happens, it’s easy to fall back on — ‘make it an instance variable!’ or ‘give it an attr_accessor!’ and it usually works. But that doesn’t make it the right decision. The why of that is buried in what happens when you do each of those:
#When you do this:
attr_reader :name
#Ruby creates this for you behind the scenes
def name
@name
end
#When you do this:
attr_writer :name
#Ruby creates this for you behind the scenes:
def name=(value)
@name = value
end
#When you do this: attr_accessor :name
#Ruby creates both of these for you behind the scenes:
def name
@name
end
def name=(value)
@name = value
end
So even though the code you write looks very nearly identical, what is happening behind the scenes is not the same. If your app is small and isn’t going to change often; if you’re the only person who is going to work on it, there’s not much harm in creating an accessor if all you really need is a reader, but think about:
So, note to self (and you): don’t create an accessor unless you actually need one.