I was just reminded of why I use private att_reader
in my code.
I know the advice is to always use an interface but a point of discussion between myself and a colleague has been why not to use an instance variable, with the argument that it is much more readable.
I have to agree with him in that with @foo
it's obvious that it's an instance variable being referred to. I agree it's better than plain old foo
in terms of readability.
That is about where the benefit ends however and there is a huge downside. Consider the following:
class Foo
def initialize(some_variable) = @some_variable = some_variable
def some_op = @some_varible
end
class BetterFoo
def initialize(some_variable) = @some_variable = some_variable
def some_op = some_varible
private attr_reader :some_variable
end
puts "----"
puts Foo.new("BAR").some_op
puts "----"
puts BetterFoo.new("BAR").some_op
puts "----"
The typo in the above is probably glaringly obvious since it's a small piece of code ... did you spot it? If not compare the output:
ruby some_variable.rb
----
----
some_variable.rb:10:in `some_op': undefined local variable or method `some_varible' for #<BetterFoo:0x00007fdba9d26090 @some_variable="BAR"> (NameError)
def some_op = some_varible
^^^^^^^^^^^^
Did you mean? some_variable
@some_variable
from some_variable.rb:18:in `<main>'
Did you spot it now?
IMO the use of a private attr_reader
so as to ensure the variable you are using has been initialised to a value other than nil overrides any readability argument; let's not mention that it more easily allows the interface to be changed internally in the future should the need arise. The fact that it's private makes it an implementation detail but an implementation detail that will save you a lot of time.
Top comments (0)