zoukankan      html  css  js  c++  java
  • ruby的动态性

    #由于eval 方法不会检查字符串的内容,这样很不安全
    #所以我们经常用 module_eval   class_eval    instance_eval 来动态执行字符串形式的代码
    
    class String
      def truncate(n)
         self[0,n]
      end
    
      for i in [5,8,10,20]
         module_eval "def truncate_#{i} #注意调用的时候不能吧参数换行,否则会报参数错误
                truncate #{i}
            end"
      end
    end
    
      puts "abcdef".truncate(2)
      puts "abcdef".truncate_5
      puts "abcdef".truncate_10
    
    #对象的send 方法,用于动态调用对象的方法,已字符串为例子:
    
    mymethod = "upcase"
    puts "abcd".send(mymethod)
    mymethod = "downcase"
    puts "ABCD".send(mymethod)
    
    #动态获得方法
    puts Object.methods    #返回Object 对象的共有方法
    puts Object.instance_methods #返回Object 对象的公开实例方法
    puts String.method_defined?(:reverse) #返回String 对象是否定义了一个 reverse 的实例方法
    puts "str".respond_to?(:upcase)  #返回类是否能相应某实例方法的调用
    
    #const_get 的两个用处:可以获得模块或类中的常量,也可以根据某个类名称创建某个类的实例。
    #简单概括就是  可以获得 常量性质的
    class_name = "Array"
    array_class = Object.const_get(class_name)
    puts array_class.new  => []
    
    #获取和设置实例变量 
    #@aa = 1
    #pust self.instance_variable_get("@aa"")
    #self.instance_variable_set("@aa",2)
    #puts @aa =>2
    
    #动态定义方法
    class Myclass
      def self.new_method(name,&block)
        define_method(name,&block)      #动态定义方法
      end
    end
    
    Myclass.new_method(:my_new_method){ puts "my_new_method"}
    Myclass.new.my_new_method
    
    #调用没定义的方法 ruby 会调用 method_missing(name,*args)
    #若调用没定义的常量, 会调用   const_missing(name)
    
    class Module
      def const_missing(name)
        puts "const: #{name} no define"
      end
    
      def method_missing(name,*args)
        puts "method: #{name} no define"
      end
    end
    
    puts String.unknown_method
    puts String::Unknown_Const
    
    #利用 const_missing 和 method_missing 可以动态实现无穷多个有规则的方法。
    #利用 const_missing 自动创建所有字母的 ASCII 码
    #很有用的一段代码
    class Module
      def const_missing(name)
        match = /^ASCII_FOR_([A-Z]|[a-z])$/.match(name.to_s)
        if match
          return match[1][0]   #返回 ASCII 码
        else
          return NoMethodError  #报错
        end
      end
    end
    
    puts ASCII_FOR_A
    puts ASCII_FOR_z
    #method_missing 查找学生,很有用的感觉
    class Student
      attr_accessor :name, :sex, :age, :grade
    
      def initialize(_name,_sex,_age,_grade)
        self.name = _name
        self.sex = _sex
        self.age = _age
        self.grade = _grade
      end
    
      def to_s   #覆盖自身的 to_s方法
        self.name
      end
    
    end
    
    
    class School < Array
       def find_student(by,value)     #查找学生
         puts by
         self.find_all{|s| s.send(by)==value}
       end
    
       def add_student(student)
         self<<student
       end
    
       def method_missing(name,argument)
         match = /^find_student_by_([a-z]+)$/.match(name.to_s)
         if match
           find_student match[1],argument
         else
           raise NoMethodError
         end
       end
    end
    
    school = School.new
    school.add_student(Student.new("zhangsan","male",16,"3"))
    school.add_student(Student.new("lisi","male",13,"1"))
    school.add_student(Student.new("liyuan","female",16,"3"))
    school.add_student(Student.new("wangqiang","male",16,"2"))
    
    
    puts school.find_student_by_name("zhangsan")
    puts "=========="
    puts school.find_student_by_sex("male")
    puts "=========="
    puts school.find_student_by_age(13)
    puts "=========="
    puts school.find_student_by_grade("3")
    
    
    #动态删除定义
    #undef 取消定义的方法
    #Module类还提供了下面方法来删除定义
    #remove_method    删除方法   删除当前的方法定义
    #undef_method    删除方法   连父类的方法也删除
    #remove_const    删除常量
    
    #eg:
     def test_function
       puts "test_function"
     end
    
     undef test_function
     
     # test_function 报错,被 undef 了
     class Myclass
       def method1
         puts "method1"
       end
       
       def method2
         puts "method2"
       end
     end
    
     class MySubclass < Myclass
       def method1
         puts "method1"
       end
       def method2
         puts "method2"
       end
       remove_method :method1
       undef_method :method2
     end
    
     sub_class = MySubclass.new
     sub_class.method1  #输出 method1
    # sub_class.method2  #报错  因为父类的方法也被删除了
  • 相关阅读:
    RTLabel 富文本
    代码复用,优化时间
    (转)分享一些免费的接口.无意中查找资料发现
    新手之使用git
    ios 清理缓存
    (转)IOS崩溃 异常处理(NSSetUncaughtExceptionHandler)
    UIApplication的理解
    新提交审核app保留检查更新入口将被拒绝
    (转)免费天气预报接口API以及全国所有地区代码!!
    Cesium快速上手9-Camera和Scene中的其他函数使用
  • 原文地址:https://www.cnblogs.com/laoquans/p/3181986.html
Copyright © 2011-2022 走看看