`

娃娃鸭学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
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics