3

client_options2 つのインターフェイス メソッドとを公開するクラスがuser_optionsあり、この祖先レベルでは、それらは と同等default_optionsです。default_options他の開発者に直接実装してほしくないので、プライベートです。

class Foo
  def client_options
    default_options
  end
  def user_options
    default_options
  end

  private
    def default_options
      { foo: :bar }
    end
end

数行のコードを節約するために、メソッドにエイリアスを設定したいと思いました。

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

  private
    def default_options
      { foo: :bar }
    end
end

ただし、alias_methodパブリック メソッドのエイリアスのみです。

このブログでプライベート メソッドをエイリアスする方法を見つけました。

class Foo
  def default_options
    { foo: :bar}
  end

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

しかし、それは少し読みにくいです。

プライベートメソッドをエイリアスするためのより直接的な解決策はありますか?

4

3 に答える 3

10

エイリアス、次に民営化:

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

または、この「はさみのルール」をよく知っているかどうか:

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

または、独自のalias_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 }
于 2015-08-13T08:50:04.933 に答える
1

私が良い代替手段を見つけた1つのアプローチは、プライベートメソッドをデリゲートすることですself

require 'forwardable'
class Foo
  extend Forwardable
  def_delegator :self, :default_options, :client_options
  def_delegator :self, :default_options, :user_options

  private
    def default_options
      { foo: :bar }
    end
end

f = Foo.new
f.client_options 
# => { foo: :bar }
于 2015-08-13T08:47:43.633 に答える
1

非表示にしたいメソッドを先頭に追加したモジュールに実装するのはどうですか?

module ProtoFoo
  protected
    def default_options
      {foo: :bar}
    end
end

class Foo
  prepend ProtoFoo
  def client_options; default_options end
  def user_options; default_options end
end

ユーザーが に上書きdefault_optionsFooても効果はありません。

公開されたものの後に隠されたものを書くことを主張する場合は、次のことができます。

class Foo
  def client_options; default_options end
  def user_options; default_options end
end

module ProtoFoo
  def default_options
    {foo: :bar}
  end
end
Foo.prepend ProtoFoo
于 2015-08-13T09:15:36.013 に答える