Ruby `alias_method`一个私有方法

Ruby `alias_method`一个私有方法,ruby,alias-method,Ruby,Alias Method,我有一个类,它公开了两个接口方法client\u options和user\u options,在这个祖先级别上,它们相当于default\u options。我不希望其他开发人员直接实现default\u选项,因此它是私有的 class Foo def client_options default_options end def user_options default_options end private def default_options

我有一个类,它公开了两个接口方法
client\u options
user\u options
,在这个祖先级别上,它们相当于
default\u options
。我不希望其他开发人员直接实现
default\u选项
,因此它是私有的

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\u方法
仅别名公共方法

我找到了如何在上别名私有方法:

但是,它有点不可读


是否有更直接的方法来别名私有方法?

我发现一种很好的替代方法是将私有方法委托给
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 }
别名,然后私有化:

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\u方法
like方法

  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 }

如何实现要隐藏在前置模块中的方法

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\u选项
,也不会生效

如果你坚持把隐藏的东西写在暴露的东西之后,你可以这样做:

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

您好,谢谢您的回答,但这和我在问题中发布的内容是一样的真的吗?也许这让我看到了这个问题的丑陋版本,但我看不到有人贴了出来。那么,这种方法有什么错呢?这是一种有效的方法,我并不是说我只是在寻找一种尊重“剪刀法则”的解决方案……有趣的是,我无法在谷歌上搜索任何关于这一法则的文章,但罗伯特·C·马丁(Clean Coders videos的创建者)正在谈论这一点。这是过去的一条规则,在过去,您试图将公共方法/接口方法放在代码的顶部,而将私有方法放在下面。当您将私有方法粘贴到关键字
private
下面时,Ruby很好地实现了这一点。想象一下,如果我的类有更多的私有方法,它们在private之下,而
default\u options
必须在private之上。希望我说得有道理,我用允许的注释大小来解释它:)@equivalent8你的上一个例子也不尊重这个规则。如果我要实现
Foo
子类,我希望有明确的方法定义。使用
alias\u方法
可能会节省一两行代码,但这会使理解类更加困难。
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