浏览 3849 次
精华帖 (0) :: 良好帖 (2) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2009-09-17
最后修改:2009-09-17
Ruby是靠mixin来实现多重继承的,mixin的module中的方法在类中可以被调用,就像类自己的方法一样,但这只局限于instance method,module中的class method是没法在class中直接当做类方法来调用的。 module TestModule def instance_method puts "this is a instance method in module" end def self.class_method puts "this is a class method in module" end end class TestClass include TestModule end TestClass.new.instance_method #=> this is a instance method in module TestClass.class_method #=> undefined method `class_method' for TestClass:Class (NoMethodError) 但是灵活的Ruby还是又办法给类mixin类方法的 module TestModule def self.included(recipient) recipient.extend(ModelClassMethods) end module ModelClassMethods def class_method puts "this is a class method in module" end end # class methods end class TestClass include TestModule end TestClass.class_method #=> this is a class method in module 其实instance method 也可以通过这种方法mixin,所以有人喜欢用这样的Mixin Template module TestModule def self.included(recipient) recipient.extend(ModelClassMethods) recipient.class_eval do include ModelInstanceMethods end end module ModelClassMethods def class_method puts "this is a class method in module" end end # class methods module ModelInstanceMethods def instance_method puts "this is a instance method in module" end end # instance methods end class TestClass include TestModule end TestClass.new.instance_method #=> this is a instance method in module TestClass.class_method #=> this is a class method in module 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2009-09-17
用extend不是就可以吗?
irb(main):001:0> module TestModule irb(main):002:1> def class_method irb(main):003:2> puts 'class_method' irb(main):004:2> end irb(main):005:1> end => nil irb(main):006:0> class TestClass irb(main):007:1> extend TestModule irb(main):008:1> end => TestClass irb(main):009:0> TestClass.class_method class_method => nil irb(main):010:0> |
|
返回顶楼 | |
发表时间:2009-09-17
yuan 写道 用extend不是就可以吗?
irb(main):001:0> module TestModule irb(main):002:1> def class_method irb(main):003:2> puts 'class_method' irb(main):004:2> end irb(main):005:1> end => nil irb(main):006:0> class TestClass irb(main):007:1> extend TestModule irb(main):008:1> end => TestClass irb(main):009:0> TestClass.class_method class_method => nil irb(main):010:0> 是的,我是看到一段源码是这样写的,这事mixin的一个模板,实例方法也可以这样mixin |
|
返回顶楼 | |
发表时间:2009-09-17
最后修改:2009-09-17
用extend不是就可以吗?
irb(main):001:0> module TestModule irb(main):002:1> def class_method irb(main):003:2> puts 'class_method' irb(main):004:2> end irb(main):005:1> end => nil irb(main):006:0> class TestClass irb(main):007:1> extend TestModule irb(main):008:1> end => TestClass irb(main):009:0> TestClass.class_method class_method => nil irb(main):010:0> +100 |
|
返回顶楼 | |
发表时间:2009-09-17
最后修改:2009-09-17
include是个语法(用1.class.methods.grep /include/ 不到),而extend是个方法(所有类或实例都有,因为是是根类Object的实例方法,见api:http://www.ruby-doc.org/core/classes/Object.html#M000335),用来给当前对象加载模块里的方法作为实例方法,如果当前对象是个类,那么就是成为类方法,如果是实例,那么就是实例方法:
irb(main):001:0> class C1 irb(main):002:1> end => nil irb(main):003:0> module M1 irb(main):004:1> def foo irb(main):005:2> puts "bar" irb(main):006:2> end irb(main):007:1> end => nil irb(main):008:0> C1.foo NoMethodError: undefined method `foo' for C1:Class from (irb):8 irb(main):009:0> C1.extend M1 => C1 irb(main):010:0> C1.foo bar => nil irb(main):011:0> C1.new.foo NoMethodError: undefined method `foo' for #<C1:0xb79b3f04> from (irb):11 irb(main):012:0> C1.new.extend(M1).foo bar => nil irb(main):013:0> |
|
返回顶楼 | |
发表时间:2009-09-17
我现在开始不喜欢 acts_as_XXX 这种扩展方式了,写起来太累,用起来也没有方便太多。
|
|
返回顶楼 | |
发表时间:2009-09-18
rainchen 写道 include是个语法(用1.class.methods.grep /include/ 不到)
你源码看少了,include 是个私有方法 irb(main):001:0> String.private_methods.include?("include") => true 很多的扩展都是这样加载的: String.send(:include, YourModule) |
|
返回顶楼 | |
发表时间:2009-09-18
ri Module#include看看就知道了 ruby里很多看似关键字的东西都是方法
|
|
返回顶楼 | |
发表时间:2009-09-18
最后修改:2009-09-18
hozaka 写道 rainchen 写道 include是个语法(用1.class.methods.grep /include/ 不到)
你源码看少了,include 是个私有方法 irb(main):001:0> String.private_methods.include?("include") => true 很多的扩展都是这样加载的: String.send(:include, YourModule) 恩,的确是个私有方法 irb(main):001:0> String.private_methods.grep /include/ => ["included", "include"] 我以为methods是包括了public,protected,private的,现在发现是我想当然了 String.methods.grep /include/ => ["included_modules", "include?"] 谁叫Object还有个public_methods,private_methods,protected_methods,吃一堑长一智,以后要多看api: http://www.ruby-doc.org/core/classes/Object.html#M000361 |
|
返回顶楼 | |
发表时间:2009-09-18
orange0513 写道 ri Module#include看看就知道了 ruby里很多看似关键字的东西都是方法
原来是在Module里定义的http://www.ruby-doc.org/core/classes/Module.html#M001638 我在Ojbect里没看到还以为是特殊语法了,差点误人子弟了 |
|
返回顶楼 | |