所以这出现在我的脑海里,想知道下面的一些事情发生时会发生什么.
class Test def self.abc attr_accessor :John end end object = Test.new puts "before calling class method abc: #{object.class.instance_methods(false)}" Test.abc puts "after calling class method abc: #{object.class.instance_methods(false)}"
在这里我检查的是,以这种方式创建getter和setter方法.如果是这样,那些实例方法或类方法.首先,我创建一个新对象,然后查看该对象的实例方法.在下一行之后我运行类方法abc然后再次检查对象的实例方法.那时我只能看到John和John =两种方法.这是怎么发生的?为什么运行类方法会动态地向已创建的对象添加方法?有人可以解释一下这个.
before calling class method abc: [] after calling class method abc: [:John,:John=]
解决方法
在类方法中,self就是类本身.因此,以下内容与他们最终做的相同:
class Test def self.abc # `self` in this context is Test. # This sends the message `:attr_accessor,:john` to `Test` attr_accessor :john end end class Test # `self` in this context is Test. # This sends the message `:attr_accessor,:john` to `Test` attr_accessor :john end
但是,正如您所指出的,在解析类时不会执行Test :: abc,因此不会调用attr_accessor,也不会添加实例方法.在运行时执行此操作是完全有效的,事实上,它是Rails中执行的大部分元编程的基础.
通常,如果您希望通过类方法添加访问器,则可以在定义之后调用该类方法,但仍然在类声明期间:
class Test def self.abc attr_accessor :john end abc end
这将实际运行,并在类上正确声明访问器!
至于你的问题:
How come a running of a class method dynamically add methods to already created objects?
这是因为实例化类不会在实例化时实例化类的“快照” – 它会创建一个对象,该对象将其大部分功能(包括在其上发现实例方法)委托给与之关联的类.请注意,可以在不扩展回类的实例上定义新方法:
class Test attr_accessor :foo end t1 = Test.new t2 = Test.new Test.send(:define_method,:bar) {} puts t1.respond_to? :foo # => true puts t2.respond_to? :foo # => true puts t1.respond_to? :bar # => true puts t2.respond_to? :bar # => true t1.define_singleton_method(:baz) {} puts t1.respond_to? :baz # => true puts t2.respond_to? :baz # => false
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。