`alias_method` 私有方法
`alias_method` a private method
我有一个 class 公开了两个接口方法 client_options
和 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
只能为 public 方法起别名。
我找到了如何在 this blog 上为私有方法起别名:
class Foo
def default_options
{ foo: :bar}
end
private :default_options
alias_method :client_options, :default_options
public :client_options
end
但是,它有点不可读。
是否有更直接的方法来为私有方法起别名?
我发现一个不错的替代方法是将私有方法委托给 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_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 }
如何在前置模块中实现要隐藏的方法?
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
我有一个 class 公开了两个接口方法 client_options
和 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
只能为 public 方法起别名。
我找到了如何在 this blog 上为私有方法起别名:
class Foo
def default_options
{ foo: :bar}
end
private :default_options
alias_method :client_options, :default_options
public :client_options
end
但是,它有点不可读。
是否有更直接的方法来为私有方法起别名?
我发现一个不错的替代方法是将私有方法委托给 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_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 }
如何在前置模块中实现要隐藏的方法?
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