Ruby元编程起步2

书接上回……
不过要先打个岔……

动态语言就是要动起来

Ruby被人说上亿遍是动态语言,所以咱就要动态给你们看


Array.class_eval do

def punch_horse_ass
puts "Piecehealth is a very tall, rich and handsome man!!!"
end

def say_truth
puts "OK, fine, acutally I'm a diaosi"
end

end

[1, 2, 3].punch_horse_ass

Array.class_eval {remove_method :say_truth}

[1, 2, 3].say_truth # undefined method `say_truth' for [1, 2, 3]:Array (NoMethodError)


上面这段代码只想表达,我们可以对一个类在任何时候为所欲为(说这个词的时候总是不自觉露出淫 荡的表情),于是,我们就要对刚才那个还非常嫩的类为所欲为了!

实现initialize方法:
这一步感觉没什么好说的,直接上代码吧

module Tool

def self.csv2class csv_name
klass_name = csv_name.gsub('.csv', '').gsub(/\s+/, '_').downcase.capitalize
klass = Object.const_set(klass_name, Class.new)
File.open(csv_name ) do |file|
attributes = file.readline.chomp.split(',')

klass.class_eval do

attr_accessor *attributes

define_method :initialize do |*args|
attributes.each_with_index do |attribute, i|
instance_variable_set("@#{attribute}", args[i])
end
end

end

end

end

end

Tool.csv2class "Friends.csv"
puts Friends.new('Lilei','M',26,'Worker').dept


相信有一定ruby基础的同学能看明白(看不明白的同学不用担心,上面的东西baidu google类似的内容很多,搜索一下吧),但是这些是经过我实践后得到的最佳解决方案。

我第一次接触这个时主要面临两个问题,我们一个一个说吧。
第一个是为什么一定要用define_method而不直接用def(像第一段代码一样),这样做除了装X还有什么好处?
好吧,为了不被雷劈,我们把define_method方法换成def,即

def initialize *args
attributes.each_with_index do |attribute, i|
instance_variable_set("@#{attribute}", args[i])
end
end


然后运行Tool.csv2class "Friends.csv"的时候报错:in `initialize': undefined local variable or method `attributes' for #<Friends:0x35b46d8> (NameError)

啊,原来class_eval相当于打开一个内环境,而attributes是内环境之外的,也就是说class_eval内外是两个不同的作用域,而且貌似没什么交集。

这就是我第二个问题,内环境外环境是如何交互的?
很显然用defing_method可以用到外面作用域的变量跟方法,而class_eval里面的实例变量,类变量赋值取值可以用instance_variable_set, instance_variable_get, class_variable_set, class_variable_get来实现,这样两套不同的体系在两个不同的作用域间各自运作,又可以相互通讯,实在是太妙了……貌似还缺一个洋气的名字,就叫扁平作用域吧!


(由于本人比较懒,写的时候随手写的,也没查阅什么资料,绝大部分都是凭借记忆,很多表达都不准确,只希望能帮大家理解元编程的一些东西)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值