1. Duck Typing
A. 无类型语言
不伤害reliablity 但增加productivity
So even in Java, the class is not always the type—sometimes the type is a subset of the
class, and sometimes objects implement multiple types.
Duck typing: The type of an object is determined by what it can do(behavior), not by its class.
If an object walks like a duck and talks like a duck, then the interpreter is happy to treat it as if it
were a duck.
B. Standard Protocols and Coercions
惯例协议:
1. to_s, to_i
2. to_str, to_int 严格
3. number coercions(coerce)数字的转换由class定,并且可以把参数考虑进来
A class definition is executable code.
scope operator ::
module和class可嵌套定义
2. Classes and bjects
A. 模型
A Ruby object has three components: a set of flags, some instance variables, and an
associated class. A Ruby class is an object of class Class, which contains all the object
things plus a list of methods and a reference to a superclass (which is itself another
class). All method calls in Ruby nominate a receiver (which is by default self, the
current object). Ruby finds the method to invoke by looking at the list of methods in
the receiver’s class.If it doesn’t find the method there, itlooks in any included modules,
then inits super class, modules in the superclass, and then in the super class’s superclass,
and so on.If the method cannot be found in the receiver’s class or any of its ancestors,
Ruby invokes the method method_missing on the original receiver.
virtual class 是针对每个object单建的。
一个object的class如果再度被open,那将不会再新建一个virtual class,只是修改已经建好的这个中的内容。
每include一个module,就会在super链中增加一个proxy class,这个proxy的superintendent指向Object或其他proxy,而proxy的method和instance变量都指向同一个Module中的内容。module不会多建,而proxy会有很多个,并且形成一个链。后加入的插在前面。Proxies位于Class和Object中间。
B. Class and Module Definitions
In Ruby,class and module definitions are executable code.
也就是class和module都是可以动态定义的,和编译好的语言大不相同。
Top-Level Execution Environment 就是Object的实例,所以调用puts等于调用self.puts.
3. Reflection
通过反射发现:
A. 包含的objects
ObjectSpace.each_object() {|x|}
B. class hierarchy
klass.superclass
klass.ancestors 同时还会列出混入的mixin module
C. attributes and methods of object
local_variables
o.instance_variables 执行过的函数后,会有对应的实例变量添加其中
c.class_variables
c.constants
o.methods
o.respond_to?("frozen?")
o.id
o.class
o.kind_of? Fixnum
o.instance_of? Numeric
E. 动态调用method的3种方法
1. o.send(command_string, params)
2. Method object
method = "sss".method(:length)
method.call
UnboundMethod , bind给某个object
3. eval会分析并执行一段合法的ruby代码
trane = %q{"sss".length}
eval trane
性能来说,eval慢许多。
require 'benchmark'
include Benchmark
test = "Stormy Weather"
m = test.method(:length)
n = 100000
bm(1) {|x|
x.report("call") { n.times { m.call } }
x.report("send") { n.times { test.send(:length) } }
x.report("eval") { n.times { eval "test.length" } }
}
F. System hooks 允许改变已存在函数的行为
1. 利用class-open原则,alias_method老的method,重新定义同名的method。
2. callback methods
singleton_method_added 还考虑给某个具体的实例变量增加的method
method_added 针对open一个class时
增加class method时,singleton_method_added 会被通知两次。singleton包含特殊(某个object)的意思。
调用caller得到如何到此的一个call stack(string 组成的 array)
G. YAML for Marshalling
实现to_yaml_properties方法,require yaml.
调用YAML.dump(obj)获取数据,调用YAML.load(data)还原数据。
"compile time” and “runtime.”are all the same. You can add code to a running process.
You can redefine methods on the fly, change their scope from public to private, and
so on. You can even alter basic types, such as Class and Object.
Once you get used to this flexibility, it is hard to go back to a static language such as
C++ or even to a half-static language such as Java.
But then, why would you want to do that?