Find
The Find
module supports the top-down traversal of a set of file paths.(一系列文件的路径的遍历)
我直接输入目录名字,老是说没有这个目录,文件。?
Enumerable#reduce
reduce
的第一个参数 initial 是初始值,然后这个匿名函式依序走访容器,两个参数 memo
跟 obj,前者 memo
是前一次循环的回传结果。obj
是这次走访的元素。
例子:reduce
(1..3).inject { |sum, n| sum + n }
private 和 protected 有什么差别?
http://weblog.jamisbuck.org/2007/2/23/method-visibility-in-ruby
implict [ɪm'plɪsɪt]suggested or understood without being stated directly
an implicit receiver of self
. 隐含的自己
private只能被an implicit receiver of self调用。obj调用一个public方法,并在这个public方法内部调用private方法,不要加self.
protected只可以被 receiver is self
的对象调用。obj调用一个public方法,并在这个方法内调用protected方法,加不加self关键字都可以。
module 命名空间
pasting
module Aclass Bendend
这个被 module A 包起来的 class B,如果要使用它要用 A::B
如果 module A 已经定义过了,则可以这样写:
假如在 module A 里面定义了一个跟最外层撞名的类,这时候如果要拿外层的类,需要加上 ::
符号:
模块也是类,所以可以有模块方法(类方法),写法一样。
名词释疑:方法的「接口(Interface)」指的是方法的名称和参数,方法的「实作(Implement)」指的是方法内实际要做的代码
面向对象的3个特点:
1.封装。方法的使用,只需知道接口,就可以用了,方法的实做不需要了解。
2.继承。父类定义的方法可以被子类继承。Ruby只支持单一继承,但可以使用模块混入。
3.多态。指不同形态的东西,有共同的特点,就当初同一类东西使用。
例子:
Strategy Pattern 范例: 情境是我们想要设计一个通用的数据输出功能,并且允许我们随时可以抽换不同的输出方式,例如 XML 或 JSON。思路:一个数据有格式和内容。内容不变,格式根据需要改变。
第一,定义一个数据存储类,存储data和formatter两个属性。
第二,定义2个格式类,每个类有不同的输出格式,但调用方法接口都是output(data)
第三,在数据存储类中定义output, 内容是根据格式不同调用各自的方法output.
第四,在实例化一个数据存储类时,格式属性使用格式类.new生成一个格式类的对象。
class AwesomeFormatterattr_accessor :data, :formatterdef initialize(data, formatter)data=dataformatter=formatterenddefoutputputsself.formatter.output(self.data)endendclassXMLFormatterdefoutput(data)"#{ data}"endendclassJSONFormatterdefoutput(data)"{ data: #{ data} }"endendformatter=AwesomeFormatter.new("ihower",XMLFormatter.new)formatter.output()# 输出 XML 格式 ihower
formatter.formatter=JSONFormatter.new# 动态更换不同的输出策略formatter.output()# 输出 JSON 格式
参考
- 人民邮电,找最新版本english。
Percent Strings
%() string
%w() Array of string,例子 %w(1 2) => ["1", "2"]
%r() 正则表达式
元编程: define_method
class Adef self.define_my_method(x)define_method("output_#{x}") doputs "This is #{x}"endendendclass B < A define_my_method :foo # 定义 output_foo 方法endclass C < Aself.define_my_method(:bar) # 完整的写法,类宏endB.new.output_foo # 输出 This is fooC.new.output_bar # 输出 This is bar
在 Rails 很多这样的宣告背后,都是用 define_method
做出来的:
class Firm < ActiveRecord::Basehas_many :clientshas_one :accountbelongs_to :userend# has_many 是 AciveRecord 的类方法(class method)# 其内容是动态定义出 Firm 的一堆对象方法(instance methods)firm = Firm.find(1)firm.clientsfirm.accountfirm.user
直接复写 Class 的定义去修改行为,在 Rails 中常用这招来扩增原本 Ruby 的行为,例如:
blank? 方法。检查对象是否是nil或者空字符串,空数组。
class Object # 在 Ruby 中所有的类都会继承自 Object 这个类 def blank? respond_to?(:empty?) ? empty? : !self endend
[1,2,3].blank? # false
"blah".blank? # false
"".blank? # true
nil.blank? # true
解释:Object#(:symbol)是看receiver是否对method回应,返回boolean. 数组和字符串都有empty?方法. nil是个伪变量,没有方法。它的!self就是true