Ruby动态特性的体现
- 动态执行字符串形式的代码。
- 动态获取模块或类中的常量和变量值
- 动态为类或者对象添加方法
- 对未知变量和方法的动态处理
- 动态的删除定义
动态的执行代码
class String
def truncate(n)
self[0,n] + (self.size>n ? "..." : "..")
end
for i in [5,8,10,20]
module_eval "
def truncate_#{i}
truncate #{i}
end
"
end
end
puts "abcdefg".truncate(2)
puts "abcdefg".truncate_5
puts "abcdefg".truncate_10
输出:
ab...
abcde...
abcdefg..
动态获得模块或类中的方法,常量或变量值
puts String.methods # 返回所有公开的实例方法名
puts String.instance_methods # 返回受保护的方法名
puts String.method_defined?(:reverse) # 判断是否定义了某实力方法
puts "str".respond_to?(:upcase) # 检查类是否能够响应某实例方法的调用
str = "PI"
puts Math.const_get(str)#根据常量的名称获取模块或类中常量的值
class_name = "Array"
array_class = Object.const_get(class_name) # 根据类的名称创建类实例
puts array_class.new
注意:instance_variable_get和instance_variable_set仅限于获取实例变量,如果实例中去掉@,则会报错
@aa = 1
puts self.instance_variable_get("@aa")
self.instance_variable_set("@aa",2)
puts @aa
动态定义方法
class MyClass
def self.new_method(name,&block)
define_method(name,&block)
end
end
MyClass.new_method(:my_new_method){puts "这是动态定义的新方法!"}
my_class = MyClass.new
my_class.my_new_method
# &block 表示可以引用一个代码块
coust_missing、method_missing 介绍
# 自定义不存在的常数和方法提示
class Module
def const_missing(name)
puts "常数#{name}没有定义!"
end
def method_missing(name,*args)
puts "方法#{name}没有定义!"
end
end
puts String.unknown_method
puts puts String::Unknown_Const
动态删除定义
remove_method 和 remove_const都是私有方法,只能在类或模块内部使用
def test_function
puts "test_function"
end
undef test_function #删除方法定义
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
sub_class.method2