别名实例方法时了解单例类 [英] Understanding the singleton class when aliasing a instance method

查看:97
本文介绍了别名实例方法时了解单例类的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用Ruby 1.9.2和Ruby on Rails v3.2.2 gem.我正在尝试以正确的方式"学习元编程,这时,我在RoR included do ... end块中为 instance 方法添加了别名. .org/classes/ActiveSupport/Concern.html"rel =" nofollow> ActiveSupport::Concern 模块:

I am using Ruby 1.9.2 and the Ruby on Rails v3.2.2 gem. I am trying to learn Metaprogramming "the right way" and at this time I am aliasing an instance method in the included do ... end block provided by the RoR ActiveSupport::Concern module:

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

新手"说,在Web上搜索时,我想到了singleton_class = class << self; self end语句,并使用了该语句(而不是class << self ... end块)以作用域 变量,从而使别名动态生成.

"Newbiely" speaking, with a search on the Web I came up with the singleton_class = class << self; self end statement and I used that (instead of the class << self ... end block) in order to scope the my_method_name variable, making the aliasing generated dynamically.

我想确切地了解为什么和如何 singleton_class在上述代码中的工作原理,以及是否有更好的方法(也许是更可维护和更高效的方法)一个)来实现相同的效果(锯齿,定义单例方法等),但是实现正确方法",因为我认为并非如此.

I would like to understand exactly why and how the singleton_class works in the above code and if there is a better way (maybe, a more maintainable and performant one) to implement the same (aliasing, defining the singleton method and so on), but "the right way" since I think it isn't so.

推荐答案

我推荐Yehuda Katz的

I recommend Yehuda Katz's post on metaprogamming on Ruby's self. Here's my humble summary in response to your question:

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

In Ruby, all objects have a singleton class (also known as metaclass). Objects inherit first from their singleton class invisibly, then from their explicit class. Ruby classes themselves have their own singleton classes since classes are objects as well. The class << idiom is simply Ruby's syntax for accessing the scope of an object's singleton class.

 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中的变量:

Your version of Rails actually provides singleton_class as a shortcut. Since singleton_class is an available method, you don't need to assign it to a variable in the expression singleton_class = class << self; self end:

Person.singleton_class 

person = Person.new
person.singleton_class

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

Since a class inherits directly from its singleton class, this is where we want to add class methods dynamically when metaprogramming. Ruby provides a few ways to open up the scope of an object while maintaining access to the surrounding scope: class_eval and instance_eval. There are subtle differences in the way these behave (Yehuda's post explains this), but you may use either to enter the scope of your singleton class, resolve methods on the singleton class as self and still have access to my_method_name from the surrounding scope.

所有这些,您可以对模块进行一些小的更改:

All that said, you could make a few small changes to your module:

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

这篇关于别名实例方法时了解单例类的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆