Ruby元编程起步4_Ruby_编程开发_程序员俱乐部

中国优秀的程序员网站程序员频道CXYCLUB技术地图
热搜:
更多>>
 
您所在的位置: 程序员俱乐部 > 编程开发 > Ruby > Ruby元编程起步4

Ruby元编程起步4

 2012/6/29 16:37:34  piecehealth  程序员俱乐部  我要评论(0)
  • 摘要:如果感谢大家能看到第四篇……为了答谢各位新老客户,所以本店将赠送大家装X名字一枚:metaclass(我认为面试ruby的话能说出metaclass跟扁平作用域就能说明你对ruby有一定层次的理解了。)不过首先呢,我们要知道什么是eigenclass。本人的一贯工作作风就是脏活累活给别人干,所以我就不在这里介绍eigenclass,大家可以自行baidu或者参考http://17test.info/?p=152。知道了eigenclass了,再告诉你下一个秘密:定义class跟定义方法一样
  • 标签:Ruby 编程
如果感谢大家能看到第四篇……

为了答谢各位新老客户,所以本店将赠送大家装X名字一枚:metaclass(我认为面试ruby的话能说出metaclass跟扁平作用域就能说明你对ruby有一定层次的理解了。)

不过首先呢,我们要知道什么是eigenclass。
本人的一贯工作作风就是脏活累活给别人干,所以我就不在这里介绍eigenclass,大家可以自行baidu或者参考http://17test.info/?p=152。

知道了eigenclass了,再告诉你下一个秘密:定义class跟定义方法一样,都有返回值!
turth = class A
	"The most xun national wind"
end

puts turth

虽然在class里不能用return,但是最后一句表达式的值却真的有返回。

终于要到正题了:创建类方法。
在class_eval里直接用define_method显然是不行的,define_method只能添加实例方法,但是正如我们第三篇所说,类方法就是这个类作为一个对象(Class的实例)的实例方法,所以只要我们找到这个类的类(我已经厌倦了这种表达……),然后添加实例方法即可……

Klass = Class.new

Klass.class_eval do

	define_method :instance_method_for_demo do
		puts "This is a instance method for #{self}"
	end

	self.class.class_eval do
		define_method :class_method_for_demo do
			puts "This is a class method for #{self}"
		end		
	end

end

Klass.new.instance_method_for_demo
Klass.class_method_for_demo


哈哈大功告成。
不过这样做是不对的。

虽然给Klass添加好了类方法,但是突然发现,所有类都多了一个类方法……
Array.class_method_for_demo
String.class_method_for_demo


因为上面代码中self.class就是Class,所有的类都是Class的子类,所以上面的代码相当于给每一个类都添加了一个方法……what the fxxk

说脏话显然是解决不了问题的,要解决问题首先要知道——问题是什么……
我们需要在Class里添加一个实例方法,但是我希望这个Class只属于我们的Klass……
那么,有没有只属于我们的Klass的Class呢?

eigenclass,该你出场了。

metaclass = (class << self;self;end)
这句代码单独拿出来不好理解,因为我们不知道self是什么,那我们就放进上下文中。
Klass = Class.new

Klass.class_eval do

	define_method :instance_method_for_demo do
		puts "This is a instance method for #{self}"
	end

	metaclass = (class << self; self; end)
	
	metaclass.class_eval do
		define_method :class_method_for_demo do
			puts "This is a class method for #{self}"
		end		
	end

end

Klass.new.instance_method_for_demo
Klass.class_method_for_demo

Array.class_method_for_demo
String.class_method_for_demo


到了这里我已经感觉无力解释了,只能提示一下:metaclass = (class << self; self; end)
这里面虽然有两个self,但是这两个self是不一样的……

即时还是不理解,先记住结论:在metaclass.class_eval里define_method,就可以添加类方法。
发表评论
用户名: 匿名