ruby-on-rails – 当class_eval本身足够时,为什么要使用include
在下面的代码中使用了include模块.如果删除了包含模块的方式,那么也会创建一个实例方法.那为什么用户包含模块?
http://github.com/rails/rails/blob/master/activerecord/lib/active_record/associations.rb#L1416 include Module.new { class_eval <<-RUBY,__FILE__,__LINE__ + 1 def destroy # def destroy super # super #{reflection.name}.clear # posts.clear end # end RUBY } 解决方法
首先让我们说清楚一件事.当他们在class_eval中调用super时 – 它与他们使用的包含Module.new {}的东西完全无关.实际上,在destroy方法中调用的super与回答你的问题完全无关. destroy方法中可能有任意代码.
现在我们已经把它弄开了,这就是正在发生的事情. 在ruby中,如果您只是定义一个类方法,然后在同一个类中再次定义它,您将无法调用super来访问前一个方法. 例如: class Foo def foo 'foo' end def foo super + 'bar' end end Foo.new.foo # => NoMethodError: super: no superclass method `foo' for #<Foo:0x101358098> 这是有道理的,因为第一个foo没有在某个超类中定义,也没有在查找链的任何地方定义(这是超级点的位置).但是,您可以通过以下方式定义第一个foo:当您稍后覆盖它时 – 通过调用super可以使用它.这正是他们想要用模块包含的目的. class Foo include Module.new { class_eval "def foo; 'foo' end" } def foo super + 'bar' end end Foo.new.foo # => "foobar" 这是有效的,因为当您包含模块时,ruby会将其插入到查找链中.这样,您可以随后在第二种方法中调用super,并期望调用包含的方法.大. 但是,您可能想知道,为什么不简单地包含一个没有所有技巧的模块?他们为什么使用块语法?我们知道上面的例子完全等同于以下内容: module A def foo 'foo' end end class Foo include A def foo super + 'bar' end end Foo.new.foo # => "foobar" 那他们为什么不这样做呢?答案是 – 反思的呼唤.他们需要捕获当前上下文中可用的变量(或方法),即反射. 由于它们使用块语法定义新模块,因此块内的所有变量都可用于块内.方便. 只是为了说明. class Foo def self.add_foo_to_lookup_chain_which_returns(something) # notice how I can use variable something in the class_eval string include Module.new { class_eval "def foo; '#{something}' end" } end end # so somewhere else I can do class Foo add_foo_to_lookup_chain_which_returns("hello") def foo super + " world" end end Foo.new.foo # => "hello world" 整洁,对吧? 现在让我再强调一下.在您的示例中对destroy方法的super调用与上述任何内容无关.他们出于自己的原因调用它,因为可能发生这种情况的类正在继承另一个已经定义了destroy的类. 我希望这说清楚. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
- objective-c – 如何使FMDB的数据库成为单例
- 错误记录--安装Flex Builder 3 Plug-in到eclipse出现的错误
- Flex开发中可能出现内存泄漏的地方
- C++ piecewise_linear_distribution分段线性分布随机数用法
- iPhone – 删除uitabbar控制器
- postgresql常用的查询语句
- 【开源自动化测试疑难FAQ】【WebDriver】WebDriver对SWFUpl
- c# – 如何将IEnumerable转换为IObservable?
- 果然Natt正则化P-M模型的半隐式求解格式结果
- 您没有将文件“project.xcworkspace”保存在文件夹“jDiet.