class 方法有 alias_method 吗?
Is there an alias_method for a class method?
考虑以下 class:
class Foo
def an_inst_method
'instance method'
end
def self.a_class_method
'class method'
end
alias_method :a_new_inst_method, :an_inst_method
end
这没问题,您可以毫无问题地拨打 Foo.new.a_new_inst_method
。
我希望能够有一个像 Foo.add_widget(*items)
这样的 class 方法并给它起别名,这样我就可以做类似的事情:
Foo.add_widget 'item1'
Foo.add_widgets 'item2', 'item3'
所以本质上它有一个 "ruby style" 就像 1.minute
和 2.minutes
所以我想别名 Foo.add_widget
所以调用 Foo.add_widgets
调用完全相同的方法.我知道我可以把它包起来,但我觉得我应该能够以更干净的方式做到这一点。
想想我尝试这样的事情:
class Foo
def an_inst_method
'instance method'
end
def self.a_class_method
'class method'
end
alias_method :a_new_inst_method, :an_inst_method
alias_method :a_new_class_method, :a_class_method
end
但是,我收到以下错误:
NameError (undefined method `a_class_method' for class `Foo')
所以看起来这不适用于 class 方法。我该怎么做?
好的,看起来我可以做这样的事情并且它会起作用:
class Foo
def an_inst_method
'instance method'
end
def self.a_class_method
'class method'
end
alias_method :a_new_inst_method, :an_inst_method
class << self
alias_method :a_new_class_method, :a_class_method
end
end
Foo.a_class_method # => "class method"
Foo.a_new_class_method # => "class method"
如果有人在这里有任何关于 Ruby 语言的有用信息并想提交一个全面的答案,我会给你 +1。
alias_method
对实例进行操作,因此您需要更深入地操作 Class
实例,或 class' metaclass。 Ruby 有一个可以让你脑洞大开的野生物体模型,但它也给了你无穷的力量:
class Foo
def an_inst_method
'instance method'
end
alias_method :a_new_inst_method, :an_inst_method
class << self
def a_class_method
'class method'
end
alias_method :a_new_class_method, :a_class_method
end
end
alias_method
别名接收方的实例方法。 Class 方法实际上是在 class.
的 singleton class 上定义的实例方法
class MyClass
def self.a
"Hello World!"
end
end
method_1 = MyClass.method(:a).unbind
method_2 = MyClass.singleton_class.instance_method(:a)
method_1 == method_2
#=> true
要为单例 class 上定义的实例方法设置别名,您可以使用 class << object
语法打开它。
class << MyClass
alias_method :b, :a
end
MyClass.b
#=> "Hello World!"
或者直接用singleton_class
方式引用
MyClass.singleton_class.alias_method :c, :a
MyClass.c
#=> "Hello World!"
如果您仍在 class 上下文中,self
将引用 class。所以上面也可以写成:
class MyClass
class << self
def a
"Hello World!"
end
alias_method :b, :a
end
end
或
class MyClass
def self.a
"Hello World!"
end
singleton_class.alias_method :c, :a
end
或两者结合。
您可以将 class 方法及其 alias_method
调用包装到一个单独的模块中,然后通过 extend
:
将该模块合并到您的 class 中
class Foo
def an_inst_method
'instance method'
end
alias_method :a_new_inst_method, :an_inst_method
module ClassMethods
def a_class_method
'class method'
end
alias_method :a_new_class_method, :a_class_method
end
extend ClassMethods
end
需要理解的重要一点是 在 Ruby 中没有 class 方法 这样的东西。
一个class方法实际上只是一个单例方法。 class 方法没有什么特别之处。 每个对象 都可以有单例方法。当对象是 Class
时,我们只称它们为 "class methods",因为 "singleton method of an instance of Class
" 太长且笨重。
等等!我有说 "singleton method" 吗?
另一个需要理解的重要事情是在Ruby中没有单例方法。
单例方法实际上只是单例的常规无聊的旧实例方法class。单例方法没有什么特别之处。它们只是像任何其他实例方法一样的实例方法。
事实上,Ruby只有个实例方法。没有函数,没有构造函数,没有静态方法,没有 class 方法,没有模块函数,没有单例方法。
问题不是"is this a class method, is this a singleton method",而是"which module is this method defined in?"
"Singleton methods" 是真正定义在单例中的实例方法 class。访问 foo
的单例 class 的语法是
class << foo
end
还有一个方法Object#singleton_class
,returns对象的单例class。
为什么我如此积极地强调 每个方法 都是实例方法而 class 方法不存在这一事实?因为这意味着Ruby的对象模型比人们想象的要简单得多!毕竟,在您的问题中,您已经表明您知道如何为实例方法设置别名,但您说您不知道如何为 class 方法设置别名。但是,那是错误的!您 知道如何为 class 方法设置别名,因为 它们只是实例方法。如果你被正确地教导了这个事实,你永远不需要问这个问题!
一旦你明白了每个方法都是一个实例方法,而我们所说的"singleton methods"只是单例的实例方法class,解决方案就很清楚了:
singleton_class.alias_method :a_new_class_method, :a_class_method
注意:上面写的"there is no such thing as X",我的意思是"there is no such thing as X in the Ruby language"。这确实 不 意味着 在 Ruby 社区.
中不存在这些概念
我们经常谈论 "singleton methods" 和 "class methods",只是因为它比谈论 "instance methods of the singleton class" 或 "instance methods of the singleton class of an object which happens to be an instance of the Class
class" 更容易。 Ruby核心库中甚至还有Object#define_singleton_method
, Object#singleton_method
, Object#singleton_methods
, Module#private_class_method
, Module#public_class_method
, and Module#module_function
这样的方法。但请务必记住,这些 不是 语言概念。这些是 社区 概念,只存在于我们的头脑中 和一些库方法的名称中。
考虑以下 class:
class Foo
def an_inst_method
'instance method'
end
def self.a_class_method
'class method'
end
alias_method :a_new_inst_method, :an_inst_method
end
这没问题,您可以毫无问题地拨打 Foo.new.a_new_inst_method
。
我希望能够有一个像 Foo.add_widget(*items)
这样的 class 方法并给它起别名,这样我就可以做类似的事情:
Foo.add_widget 'item1'
Foo.add_widgets 'item2', 'item3'
所以本质上它有一个 "ruby style" 就像 1.minute
和 2.minutes
所以我想别名 Foo.add_widget
所以调用 Foo.add_widgets
调用完全相同的方法.我知道我可以把它包起来,但我觉得我应该能够以更干净的方式做到这一点。
想想我尝试这样的事情:
class Foo
def an_inst_method
'instance method'
end
def self.a_class_method
'class method'
end
alias_method :a_new_inst_method, :an_inst_method
alias_method :a_new_class_method, :a_class_method
end
但是,我收到以下错误:
NameError (undefined method `a_class_method' for class `Foo')
所以看起来这不适用于 class 方法。我该怎么做?
好的,看起来我可以做这样的事情并且它会起作用:
class Foo
def an_inst_method
'instance method'
end
def self.a_class_method
'class method'
end
alias_method :a_new_inst_method, :an_inst_method
class << self
alias_method :a_new_class_method, :a_class_method
end
end
Foo.a_class_method # => "class method"
Foo.a_new_class_method # => "class method"
如果有人在这里有任何关于 Ruby 语言的有用信息并想提交一个全面的答案,我会给你 +1。
alias_method
对实例进行操作,因此您需要更深入地操作 Class
实例,或 class' metaclass。 Ruby 有一个可以让你脑洞大开的野生物体模型,但它也给了你无穷的力量:
class Foo
def an_inst_method
'instance method'
end
alias_method :a_new_inst_method, :an_inst_method
class << self
def a_class_method
'class method'
end
alias_method :a_new_class_method, :a_class_method
end
end
alias_method
别名接收方的实例方法。 Class 方法实际上是在 class.
class MyClass
def self.a
"Hello World!"
end
end
method_1 = MyClass.method(:a).unbind
method_2 = MyClass.singleton_class.instance_method(:a)
method_1 == method_2
#=> true
要为单例 class 上定义的实例方法设置别名,您可以使用 class << object
语法打开它。
class << MyClass
alias_method :b, :a
end
MyClass.b
#=> "Hello World!"
或者直接用singleton_class
方式引用
MyClass.singleton_class.alias_method :c, :a
MyClass.c
#=> "Hello World!"
如果您仍在 class 上下文中,self
将引用 class。所以上面也可以写成:
class MyClass
class << self
def a
"Hello World!"
end
alias_method :b, :a
end
end
或
class MyClass
def self.a
"Hello World!"
end
singleton_class.alias_method :c, :a
end
或两者结合。
您可以将 class 方法及其 alias_method
调用包装到一个单独的模块中,然后通过 extend
:
class Foo
def an_inst_method
'instance method'
end
alias_method :a_new_inst_method, :an_inst_method
module ClassMethods
def a_class_method
'class method'
end
alias_method :a_new_class_method, :a_class_method
end
extend ClassMethods
end
需要理解的重要一点是 在 Ruby 中没有 class 方法 这样的东西。
一个class方法实际上只是一个单例方法。 class 方法没有什么特别之处。 每个对象 都可以有单例方法。当对象是 Class
时,我们只称它们为 "class methods",因为 "singleton method of an instance of Class
" 太长且笨重。
等等!我有说 "singleton method" 吗?
另一个需要理解的重要事情是在Ruby中没有单例方法。
单例方法实际上只是单例的常规无聊的旧实例方法class。单例方法没有什么特别之处。它们只是像任何其他实例方法一样的实例方法。
事实上,Ruby只有个实例方法。没有函数,没有构造函数,没有静态方法,没有 class 方法,没有模块函数,没有单例方法。
问题不是"is this a class method, is this a singleton method",而是"which module is this method defined in?"
"Singleton methods" 是真正定义在单例中的实例方法 class。访问 foo
的单例 class 的语法是
class << foo
end
还有一个方法Object#singleton_class
,returns对象的单例class。
为什么我如此积极地强调 每个方法 都是实例方法而 class 方法不存在这一事实?因为这意味着Ruby的对象模型比人们想象的要简单得多!毕竟,在您的问题中,您已经表明您知道如何为实例方法设置别名,但您说您不知道如何为 class 方法设置别名。但是,那是错误的!您 知道如何为 class 方法设置别名,因为 它们只是实例方法。如果你被正确地教导了这个事实,你永远不需要问这个问题!
一旦你明白了每个方法都是一个实例方法,而我们所说的"singleton methods"只是单例的实例方法class,解决方案就很清楚了:
singleton_class.alias_method :a_new_class_method, :a_class_method
注意:上面写的"there is no such thing as X",我的意思是"there is no such thing as X in the Ruby language"。这确实 不 意味着 在 Ruby 社区.
中不存在这些概念我们经常谈论 "singleton methods" 和 "class methods",只是因为它比谈论 "instance methods of the singleton class" 或 "instance methods of the singleton class of an object which happens to be an instance of the Class
class" 更容易。 Ruby核心库中甚至还有Object#define_singleton_method
, Object#singleton_method
, Object#singleton_methods
, Module#private_class_method
, Module#public_class_method
, and Module#module_function
这样的方法。但请务必记住,这些 不是 语言概念。这些是 社区 概念,只存在于我们的头脑中 和一些库方法的名称中。