zoukankan      html  css  js  c++  java
  • [转]Ruby之类的真相

    打开类和猴子补丁 
    在Ruby中,类定义的方法和其他的语句没有任何区别,都是一行一行的执行下去的。如下例子: 

    Ruby代码  收藏代码
    1. class Example  
    2.   def method_1  
    3.     puts "method 1"  
    4.   end  
    5. end  
    6. class Example  
    7.   def method_2  
    8.     puts "method 2"  
    9.   end  
    10. end  


    本例中,当第一次定义Class Example的时候,还没有一个叫做Example的Class存在,因此,Ruby开始定义这个类,当后面在定义这个类时,Ruby会发现该类已存在,并返回这个类,而不是定义一个新类。 

    因为这个特性,因此,Ruby天生具有打开一个已经存在的类,并动态修改其内容的能力,即使其是标准类库的类也不例外。比方说,可以给SDK的String类添加一个去除String中的标点符号和特殊字符的方法:to_alphanumeric

    Ruby代码  收藏代码
    1. class String  
    2.   def to_alphanumeric  
    3.     gsub /[^ws]/, ''  
    4.   end  
    5. end  
    6. “H&&^^ello”.to_alphanumeric  #==>Hello  


    ,然后,所有的String对象都具备“to_alphanumeric”的能力了,这种技术一般简称为打开类技术。 

    上面描述的打开类技术其实是隐含了一定的风险的,尤其是在大型系统中使用打开类技术扩展标准类库时,因为,很多开发人员都在扩展类,当多个扩展方法的名字一样时, 后定义的总会覆盖掉前面,从而导致整个系统的崩溃,业界把这种鲁莽的修改类的方式简称为猴子补丁(Monkey Patch)。因此在使用打开类技术时,一定要慎之又慎。 

    类的真相 
    实例变量 
    在Ruby中,实例变量是存储在对象中,但是,其于该对象的类没有关系,当给对象的实例变量赋值时,该实例变量就生成了,说白了,实例变量就像是一个挂载在对象上的HashMap,每个对象都可以用自己不同的HashMap, 如下例: 

    Ruby代码  收藏代码
    1. class Person  
    2.   def name  
    3.     @name = "xianlinbox"  
    4.   end  
    5. end  
    6. p = Person.new  
    7. puts p.instance_variables      #==>nil  
    8. p.name  
    9. puts p.instance_variables      #==>@name  



    方法 
    作为一个对象,除了有实例变量(也可以称之为属性),还需要有方法。 但是在Ruby中,关于方法的定义并不在对象中,而是在对象自身的类中,这是因为“共享同一个类的对象也必须共享同样的方法”。但是,不能说Class有一个叫做“method”的方法,因为无法使用"Class.method"调用该方法,而要说Class有一个实例方法“method”,这意味着必须创建该类的实例对象,通过实例对象调用该方法。 

    如果要定义类方法,那么在定义方法的时候,必须加类名前缀,如下: 

    Ruby代码  收藏代码
    1. class Person  
    2.   def Person.name  
    3.     @name = "xianlinbox"  
    4.   end  
    5. end  



    类本身也是对象 
    在Ruby中Class本身也是一个对象,关于对象的所有规则都适用于Class. 

    Ruby代码  收藏代码
    1. puts "hello".class                   #=> String  
    2. puts String.class                     #=> Class  
    3. puts Class.class                     #=> Class  
    4. puts Class.instance_methods(false)   #=> [:superclass,:allocate,:new]  
    5. puts Class.instance_variables        #=> nil  



    类的继承体系 

    Ruby代码  收藏代码
    1. puts String.superclass        #=> Object    
    2. puts Class.superclass         #=> Module  
    3. puts Module.superclass        #=> Object  
    4. puts Object.superclass        #=> BasicObjec  
    5. puts BasicObject.superclass   #=> nil  
      • BasicObject是继承体系的根节点。
      • 所有类都继承自Object。
      • Class是对Module的继承增强,增加了new()和allocate()方法以创建实例。
  • 相关阅读:
    MySql数据库的导入_命令工具
    Java_JVM学习笔记(深入理解Java虚拟机)___重点
    HTML——<meta http-equiv="content-type" content="text/html; charset=UTF-8">
    HTML——表格table标签,tr或者td
    Java _Map接口的使用(转载)
    Java_Web _Servlet生命周期实验
    Java_Web___字符串转码String.getBytes()和new String()——(转)
    Java_Iterator-------迭代器配合Listarray使用,具有更多的功能(转载)
    Java_LIST使用方法和四种遍历arrayList方法
    Java_web 乱码和一些地址输错的问题(原创)
  • 原文地址:https://www.cnblogs.com/linganxiong/p/6110026.html
Copyright © 2011-2022 走看看