簡體   English   中英

`alias_method`是一種私有方法

[英]`alias_method` a private method

我有一個暴露兩個接口方法client_optionsuser_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

但是,它有點難以理解。

是否有更直接的解決方法來為私有方法添加別名?

別名,然后私有化:

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 }

我找到一個好方法的一種方法是將私有方法委托給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 }

如何在前置模塊中實現要隱藏的方法?

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

即使用戶覆蓋Foo default_options ,它也不起作用。

如果你堅持在暴露的東西之后寫下隱藏的東西,你可以這樣做:

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM