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 # (NameError)

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

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


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

你可能感兴趣的:(ruby,元编程)