nine
2015-01-01 02:54:10 +08:00
python不太了解,以下特性不知道在java里有没有
-------------------------
php中
1 变量的变量
$foo()
(new $bar)->$boobar()
根据的变量的值来运行某个函数/方法,这些是动态的,
2 __call($method_name , $params)
如果有一堆 “find_by_字段名” 的方法,
都是要生成 select * from table_name where 字段名 = '$params'的语句,嫌麻烦怎么办
可以在类里定义 __call($foo , $params) {
正则提取$foo , 如果含有 "find_by_(.*)" ,那么根据正则匹配的字符,执行语句
}
(具体用法其实很多,好久没写了,一时想不起来。这个用法从架构设计上,我其实觉得不怎么智慧)
注意,事实上这里并没有生成真正的method
--------------------------
而“运行时改变其结构”,还是要看ruby了
1 ruby元编程最最最最核心的、经典的“打开类”
class Foo
def bar
puts 'bar'
end
end
class Foo
def foobar
puts 'foobar'
end
end
这样写不会报错,不是重复定义类,而是把类打开了,重新给类追加了一个方法(也可以是覆盖)。
(用法,可以根据input的不同,选择添加动态添给类加哪些方法。)
所以也可以在任何位置,修改任何库的的方法。
你觉得哪个库不好用,require 之后,立刻在你的代码里“打开类”,并修改其内部实现,以完成你的需求(这称之为 monkey patch)
monkey patch很强大,也很容易造成混乱,是把双刃剑,也是ruby最“动态”的地方之一。
重要的一点,是你可以修改任何核心库的内部实现(把runtime搞挂是很easy的事,这个有点类似于js的prototype。“prototype.js”库也是rails团队做的,得名与对prototype的patch,其实是用ruby的思维方式写js,其实不是很好,所以也边缘化了)
2 instance_eval() 类似“打开类”,但是可以方便的把外部的变量带进去,并访问内部属性(ruby的实例属性都是私有的,没有public)
3 block 代码块
method不但可以传入参数,还可以传入一段代码 do end 之间的代码
而method运行时,内部的x, y , z 变量可以在传入的代码中运行。
object.foo(params1 , params2) do |x , y ,z |
#x = x + 1
#y = x + z
end
4 代码块可以保存在Proc对象里,用以延迟执行
5 用send() 给method发消息
用于动态调用方法 类似php里的 ${foo}()
6 method_missing() 类似php 的__call()
没有生成真正的method
7 define_method() 动态定义方法
功能类似method_missing()
但是定义的位置和时机更灵活
而且这里生成的是真正的method
比如有一个二维hash,里面的键值都不一样,可以根据里面的键值,来生成对象,并动态定义他们的method