rubyalias-method

`alias_method` a private method


I have a class that exposes two interface methods client_options and user_options, and at this ancestry level, they are equivalent to default_options. I don't want other developers to implement default_options directly, hence it's private.

class Foo
  def client_options
    default_options
  end
  def user_options
    default_options
  end

  private
    def default_options
      { foo: :bar }
    end
end

To save some lines of code, I wanted to alias the methods:

class Foo
  alias_method :client_options, :default_options
  alias_method :user_options, :default_options

  private
    def default_options
      { foo: :bar }
    end
end

but alias_method only aliases public methods.

I found how to alias private methods on this blog:

class Foo
  def default_options
    { foo: :bar}
  end

  private :default_options
  alias_method :client_options, :default_options
  public :client_options
end

but, it's little bit unreadable.

Is there a more straight solution to alias a private method?


Solution

  • Alias, then privatize:

    alias_method :client_options, :default_options
    alias_method :user_options, :default_options
    private :default_options
    

    Or, whether you are so aware of this “scissors rule”:

    %i(client_options user_options).each do |m|
      define_method m { default_options }
    end
    

    Or create your own alias_method alike method

      module AliasPrivateMethod
        def alias_private_method_to_interface(name, original_name)
          define_method(name) do |*args, &block|
            send(original_name, *args, &block)
          end
        end
      end
    
      class Foo
        extend AliasPrivateMethod
        alias_private_method_to_interface(:client_options, :default_options)
        private
          def default_options
            { foo: :bar }
          end
      end
    
      foo = Foo.new
      foo.public_methods(false) # => [:client_options]
      foo.client_options        # => { foo: :bar }