gpt4 book ai didi

ruby-on-rails - 为实例方法起别名时理解单例类

转载 作者:太空宇宙 更新时间:2023-11-03 17:25:29 25 4
gpt4 key购买 nike

我正在使用 Ruby 1.9.2 和 Ruby on Rails v3.2.2 gem。我正在尝试以“正确的方式”学习元编程,此时我在 included do ... end 中为一个实例 方法添加了别名RoR 提供的区 block ActiveSupport::Concern 模块:

module MyModule
extend ActiveSupport::Concern

included do
# Builds the instance method name.
my_method_name = build_method_name.to_sym # => :my_method

# Defines the :my_method instance method in the including class of MyModule.
define_singleton_method(my_method_name) do |*args|
# ...
end

# Aliases the :my_method instance method in the including class of MyModule.
singleton_class = class << self; self end
singleton_class.send(:alias_method, :my_new_method, my_method_name)
end
end

“新手”来说,通过网络搜索,我找到了 singleton_class = class << self; self end语句,我使用它(而不是 class << self ... end block )来作用域 my_method_name变量,使别名动态生成。

我想确切地了解为什么如何 singleton_class在上面的代码中工作,如果有更好的方法(也许是一种更易于维护和更高效的方法)来实现相同的方法(别名,定义单例方法等),但是“正确的方法”,因为我认为它不是'是这样。

最佳答案

我推荐 Yehuda Katz 的 post on metaprogamming on Ruby's self .以下是我对您问题的简单总结:

在 Ruby 中,所有对象都有一个单例类(也称为元类)。对象首先从它们的单例类中无形地继承,然后从它们的显式类中继承。 Ruby 类本身有自己的单例类,因为类也是对象。 class <<习语只是 Ruby 用于访问对象的单例类范围的语法。

 class Person
class << self
# self in this scope is Person's singleton class
end
end

person = Person.new
person_singleton_class = class << person; self; end

您的 Rails 版本实际上提供了 singleton_class作为捷径。自 singleton_class是一种可用的方法,您不需要将其分配给表达式 singleton_class = class << self; self end 中的变量:

Person.singleton_class 

person = Person.new
person.singleton_class

由于一个类直接继承自它的单例类,这就是我们在元编程时要动态添加类方法的地方。 Ruby 提供了几种方法来打开对象的范围,同时保持对周围范围的访问:class_evalinstance_eval .它们的行为方式存在细微差别(Yehuda 的帖子对此进行了解释),但您可以使用其中一种方法进入单例类的范围,将单例类上的方法解析为 self。并且仍然可以访问 my_method_name从周边范围。

总而言之,您可以对模块进行一些小改动:

module MyModule
extend ActiveSupport::Concern

included do
# Builds the instance method name.
my_method_name = build_method_name.to_sym # => :my_method

# Defines the :my_method instance method in the including class of MyModule.
define_singleton_method(my_method_name) do |*args|
# ...
end

singleton_class.class_eval do
# method resolution in scope of singleton class
alias_method :my_new_method, my_method_name
end

end

end

关于ruby-on-rails - 为实例方法起别名时理解单例类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12937209/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com