娃娃鸭学Ruby-18、对象
对象
Objects
Ruby是纯粹的面向对象的语言:所有的值都是对象,而且没有基本类型和对象类型的区别。
所有对象都继承一个Object类,共享此类中的方法
1、对象引用
在Ruby中使用对象时,其实是在使用对象的引用。
s="Ruby"
t=s #只是引用,t和s指向同一个值
t[-1]="" # 修改t 同时修改s
print s # "Rub"
t="Java" #这时t指向另一对象
print s,t # Prints "RubJava"
在Ruby中,当把一个对象传递给一个方法时,其实传递的是该对象的引用,被传递的是对象本身,也不是一个指向该对象的引用的引用。换言之,方法实参是通过值而不是引用来传递,只不过被传递的值正好是对象的引用。
会修改引用的底层对象。
立即值
2、对象生命周期
Ruby内建类都具有字面量方法,只须直接将这些值写入代码。
new方法
myObject =myClass.new
new是Class类的一个方法
1)为新对象分配内存
2)调用对象的initialize方法初始化这个新建的”空“对象的状态
3)传递给new方法的参数。
initialize方法用来完成必须的初始化
工厂方法
Ruby永远不需要显式释放对象
垃圾收集(garbage collection)
3、对象标识
每个对象都有一个对象标识符,它是一个Fixnum,可通过object_id 方法来获得
该方法的返回值在该对象的生命周期是独一无二且恒久不变的,只要该对象是可访问的,就一直持有同一ID,其他对象也不会共享
id方法是object_id的同义词
__id__是object_id的同义词
4、对象的类和对象的类型
o="test"
o.class # Returns String class
o.class.superclass # Object
o.class.superclass.superclass # nil
Ruby1.9中Object不再是类继承结构的真正根元素了:
#Ruby1.9 only
Object.superclass # BasicObject
BasicObject.superclass #nil
检查对象
o.class==String # true
instance_of? 同样
o.instance_of? String # true
is_a?
kind_of? 同义词
x=1
x.instance_of? Fixnum # true
x.instance_of? Numeric # false
x.is_a? Fixnum # true
x.is_a? Integer # true
x.is_a? Numeric # true
x.is_a? Comparable # true
x.is_a? Object #true
==
Numeric==x # true
<<
数组,字符串,文本及其他IO定义为追加操作(append operator)
o.respond_to? :"<<" # true if o has an << operator
5、对象的相等性
1) equal?方法
equal?方法由Object定义,测试两个值是否引用了同一个对象
a="Ruby"
b=c="Ruby"
a.equal?(b) # false
b.equal?(c) # true
按照惯例,子类永远不要重写equal?方法
另一个检查两个对象
object_ida.object_id==b.object_id #works like a.equal?(b)
2)==操作符
相等性比较
在Object中它是equal?方法的同义词
大多数类都重定义这个操作符
a="Ruby"
b="Ruby"
a.equal?(b) #false
a==b #true
注意:
同Java正好是相反的。
!=
3)eql?方法
Object将eql?方法定义成equal?方法的同义词
重定义了eql?方法的类通常将其作为一个严格版的==操作符,不允许进行类型转换
1==1.0 # true
1.eql?(1.0) #false
4)===操作符
条件相等性操作符
case when
(1..10)===5 #true
/\d+/==="123" # true
String==="s" #true
:s==="s" #true in Ruby 1.9
5)=~操作符
模式匹配
2011-4-7 21:16 danny
6、对象的顺序
<=>
1<=>5 # -1
5<=>5 # 0
9<=>5 #1
"1"<=>5 # nil
<
<=
==
>=
>
1.between?(0,10) # true 0<=1<=10
nan
nan=0.0/0.0 #
nan<0 # false
nan>0 #false
nan==0 #false
nan==nan #false
nan.equal?(nan) #true
7、对象的转换
1)显式转换
to_s String
to_i Integer
to_f Float
to_a Array
注意:
不会自动进行to_s转换,但内插到双引号的字符串自动to_s转换
2)隐式转换
Ruby1.8
Exception 类似字符串的对象
e=Exception.new("not really an exception")
msg="Error:"+e # String concatenation with an Exception
3)转换函数
Kernel模块定义了四个转换函数:
Array
Float
Integer
String
4)算术操作符的类型强制转换
coerce转换方法
类型转换成调用者的类型或更一般的兼容类型
5)布尔类型转换
true
false to_s 返回 "true" "false"
在布尔表达式里,任何不同于false或nil的值都表现像true一样
nil 则表现得像false,但是不能转换成true或false
if x!=nil
puts x
end
if x
puts x
end
以上两相同
同C或javascript区别:0,0.0 空字符串""的值表现得像true。
8、拷贝对象
Object
clone
dup
返回对象的浅拷贝
clone和dup区别:
clone会拷贝一个对象的被冻结(frozen)和受污染(tainted)状态
dup仅仅拷贝受污染状态,在一个被冻结的对象上调用dup方法将返回一个未被冻结副本
clone方法会拷贝对象的所有单键方法,dup不会
9、编组对象
Marshal.dump
Marshal.load
Marshal.dump和Marshal.load方法的用法是创建对象的深拷贝
def deepcopy(o)
Marshal.load(Marshal.dump(o))
end
10、冻结对象
freeze方法将任何对象冻结起来,一个被冻结的对象将变得不可改变
所有的内部状态都不能被改变,而对其可变方法的调用也会失败
s="ice"
s.freeze
s.frozen? # true
s.upcase! #typeError
s[0]=nil #typeError
11、污染对象
避免SQL注入攻击及类似的安全风险
解决方法:
可以通过调用其taint方法将任何对象标记成受污染的(tainted)。一旦一个对象成了受污染的,那么任何源自它的对象都将成为受污染的。 tainted?测试
s="untrusted"
s.taint
s.tainted? #true
s.upcase.tainted? #true
s[3,4].tainted? #true
2011-4-8 14:10 danny