HeadFirst Ruby 第七章总结 references

前言

这一章的内容关于 references,讲了当 Ruby 程序中可能会遇到关于 reference 与 object 之间概念混淆而导致的问题.

导言

本章从一个 astronomer 发现 star 并且为之命名的问题展开, astronomer 准备运用前一个 star 当作一个模版,赋值给以后的 star,问题出现为最后前面的 star 数据全部丢失.
本章后面也讲了为了达到 astronomer 的目标,关于 hash default object 和 hash default block 的相关应用.

代码:

class CelestialBody
attr_accesor :type, :name
end

altair = CelestialBody.new
altair.name = 'Altair'
altair.type = 'star'
polaris = altair
polaris.name = 'Polaris'
vega = polaris
vega.name = 'Vega'

puts altair.name, polaris.name, vega.name

Aliasing 这个问题

Heap、Reference 与 Object

定义:
Heap 是所有 Ruby object 存在的地方,是电脑的 memory 中的.
Ruby 通过 Reference 来 locate objects,当我们新建一个 new object 的时候, it returns a reference to itself. 
例子:
代码: car = Car.new
Car.new 新建了一个 new object, 于是 returns a reference to the new car, 之后它将值赋给 car, 因此 reference 储存在 car 这个 variable 中了.

导言中问题的解决方案——hash defalut object 与 hash default block 之战

hash default object 的问题

问题起源:

`class CelestialBody
attr_accesor :type, :name
end

default_body = CelestialBody.new
default_body.type = 'planet'
bodies = Hash.new(default_body)
//出错的地方
bodies['Mars'].name= 'Mars'
bodies['Europa'].type = 'moon'
...

问题出现在标示以后的地方,如果输入: p bodies['Mars], bodies['Europa'], 可以看到它们的地址相同.
原因在于 bodies['Mars‘] 并没有新建一个新的对象,最终的效果是修改了 defalut object 这个 object 的属性.

解决的思路

将 Defalut Object 改为 Defalut Value,并且它的值为 CelestialBody.new, Ruby 能实现这个功能的方式叫做 Hash default block

什么是 hash default block

hash default block 是 block 的一种,当遇到如下情况时,执行 hash default block 中的语句.因此它既有 hash 的响应特征,又有 block 的特征

场合:

when a key is accessed for which no value has been assigned

格式:

bodies = Hashnew do |hash,key|
//option 的部分
body = CelestialBody.new
body.type = "planet"
//
hash[key] = body
body

需要注意的几点:

  1. 赋值语句不能省略:即上面的 hash[key] = body
  2. 最后的返回语句不能省略(可只写同等效的 expression )

上述第二点用到了 Ruby 中的一个 shortcut:
value of an assignment is the same as the value being assigned.

两个 Rules

  1. Rule #1 Don't modify the default object 
  2. Assign values to the hash

总结:

If your default is a number, you can use a hash default object
If your default is anything else, you should use hash default block.





posted @ 2019-03-18 23:05  FBshark  阅读(203)  评论(0编辑  收藏  举报