Feature #18948
closedAdd `with_private_method` option to `private_constant`
Description
Problem¶
I have the following code:
module M1
CONST = 'CONST'.freeze
end
module M2
def self.included(base)
base.include M1
base.include InstanceMethods
end
module InstanceMethods
def const?(value)
M1::CONST == value
end
end
end
class C
include M2
end
C.new.const?('CONST') # => true
M2
module "inherits" M1
module using included
hook. This code works, but I prefer making constants private. However, when I add private_constant :CONST
to M1
then the code doesn't work anymore since we cannot refer M1::CONST
.
Workaround¶
One way to solve this is to define method that just returns the private constant.
# Refined version of M1 with `const` method
module M1
CONST = 'CONST'.freeze
private_constant :CONST
private
def const
CONST
end
end
# Refined version of M2, using `const` method inherited from M1
module M2
def self.included(base)
base.include M1
base.include InstanceMethods
end
module InstanceMethods
def const?(value)
const == value
end
end
end
This works anyway, but defining private method for every private constant could be cumbersome.
Solution¶
So my suggestion here is to add with_private_method
option to private_constant
method. The auto-generated private method has the same name as the given constant and just returns it. So we can do the following:
module M1
CONST = 'CONST'.freeze
private_constant :CONST, with_private_method: true
end
Now we can access CONST
with const
method. This makes is possible to refer private constants through private methods more easily, that helps some code like my example.