ion_in_minutes就是所谓的虚拟属性--原因是在它内部没有对应的实例变量而已
class Song
def dutation_in_minutes
@dutation/60.0
end
end
类方法的定义:
class Example
def Example.class_method
end
end
单件--单例 和其他构造函数
单例就是一个类只能new出一个对象,不能随便new出其他。因此需要把 类方法:new藏起来而私有化。例如:
class MyLogger
private_class_method :new
@@logger =nil
def MyLogger.create
@@logger = new unless @@logger
@@logger
end
end
通过 MyLogger.create.object_id 返回总是一种结果。
访问控制 Public(除initialize外其默认都是public) 、Protected(必须在类内或其子类中,实例对象可调用---整个家族可访问的)
、Private(不能明确被接受者调用,其接受者只能是当前锁定的self,意味着私有方法只能在对象上下文中调用。)
例如 1: ...
public :method1, :method2
protected :method3
private :method4
例如2:
private
def method
...
end
亲自测试总结:private私有表示这是实例对象的私有方法---该方法不能被接受者调用,在上下文中、继承关系中直接调用,只能在类中。
而protected受保护的表示这是实例的受保护的方法---但这方法必须有接受者调用 a.protected_method() > b.protected_method()
在上下文中、继承以及家族中,受保护的方法不能在外面被调用,只能呆在类中。
变量,不是对象,只是对象的引用。变量保存的是对象的引用,而非对象本身。
赋值别名(alias)对象,就相当于引用同一对象多个变量,但是可以用 String的dup方法避免创建别名
,
它会创建一个新的、具有相同内容的String对象 例如
person1 = "Tim" ;person2 = person1.dup; person1[0] ="J"; person1 --> "Jim" person2--> "Tim"
也可以通过冻结一个对象来阻止他人对它的改动,试图更改一个冻结的对象会引发raise一个typeErro异常
person1="Tim" ;person1.freeze
2 容器、Blocks和迭代器
容器是指含有一个或者多个对象的引用的对象。例如歌曲目录和待播放歌曲的目录。
数组:a=[1,2,3,2,9] a[start,count]返回从start开始count个对象的数组 a[-3,2]--> [3,2]
也使用range来索引 a[1..3] -> [2,3,2]
数组还有一些有用的方法,可用数组实现栈(stack)、收集(set)、队列(queue)、双向队列(dequeue)
和先进先出队列(fifo)
散
列表 hashes(也称关联数组、图map或者词典)可用任何对象做索引,但是它元素是无序的,很难使用hash来实现栈和队列。
迭代器
class SongList
def with_title(title)
@song.find{|song| title == song.name} #find就是一个迭代器,反复调用block
end
end
关于block和yield的再次研究
def three_times
yield
yield
yield
end
three_times { puts "x"} #block和three_times方法联合在一起调用
例如:
def fib_up_to(max)
i1,i2 =1,1
while i1 <= max
yield i1
i1,i2 =i2,i1+i2
end
end
fib_up_to(22) {|f| print f," "}
结果是1 1 2 3 5 8 13 21
实现迭代器:yield 和block ---{ ...} 和 do ...end
内外迭代器:ruby的迭代器集成与内部,不单单是个方法,每当产生新值就调用yield。
内迭代器不足:当把迭代器看是一个对象的时候(把迭代器传递给一个方法,而该方法需要访问有迭代器返回的每个值时),表现欠佳,
也难实现并行迭代2个收集。
外迭代器:幸运的是ruby 1.8 提供了 Generator库,该库解决了内迭代的不足,实现了外部迭代。
容器很重要,处处是容器---事务Blocks:定义在事务控制环境下,例如打开一个文件后,执行block后 文件自动关闭。
例如 File.open() { ...} 该方法的实现 归咎于 Kernel.block_given?方法的功劳。
Block闭包 :创建proc 对象时,不仅获得了