Project

General

Profile

Actions

Feature #18948

closed

Add `with_private_method` option to `private_constant`

Added by okuramasafumi (Masafumi OKURA) over 1 year ago. Updated 4 months ago.

Status:
Closed
Assignee:
-
Target version:
-
[ruby-core:109363]

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.

Actions

Also available in: Atom PDF

Like0
Like0Like0Like0Like0Like0