#由于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 #报错 因为父类的方法也被删除了