In my current project we use a whole lot of plain ruby objects. One day I was looking at them and noticed that we follow this pattern for just about everything.
[ruby]
module MyModule
class MyClass
attr_reader :params
def initialize(params:)
@params = params
end
def call
params.do_things
end
end
end
[/ruby]
The params attr_reader is used so that we don’t have to use @params throughout the object. I got used to this format and like that my ide looks better without all the @vars everywhere. But I think that it is a false contract. The public method for our objects is `call` and is all that we ever intend for someone else to use. However, the user of attr_reader says that this is a public method.
To get around this, i decided to add a quick patch so that we could still have the use of the params method locally for instance variable lookup but keep it private so that noone accidentally starts using it only for us to change it in the future.
Here is the patch I added to Object. I didn’t go all the way down to Kernel because all of our objects inherit from Object.
[ruby]
class Object
def self.private_attr_reader(*args)
args.each do |arg|
define_method(arg) { instance_variable_get("@#{arg}") }
private arg
end
end
end
[/ruby]
After adding this patch to Object we can now do this in our object and var1 and var2 would both be have attr_readers that are private to the class.
[ruby]
private_attr_reader :var1, var2
[/ruby]