Find
The Find
module supports the top-down traversal of a set of file paths.(一系列文件的路径的遍历)
prune()
我直接输入目录名字,老是说没有这个目录,文件。?
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 A
class B
end
end
这个被 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 AwesomeFormatter
attr_accessor :data, :formatter
def initialize(data, formatter)
@data = data
@formatter = formatter
end
def output
puts self.formatter.output( self.data )
end
end
class XMLFormatter
def output(data)
"<data>#{data}</data>"
end
end
class JSONFormatter
def output(data)
"{ data: #{data} }"
end
end
formatter = AwesomeFormatter.new( "ihower", XMLFormatter.new )
formatter.output() # 输出 XML 格式 <data>ihower</data>
formatter.formatter = JSONFormatter.new # 动态更换不同的输出策略
formatter.output() # 输出 JSON 格式 { data: ihower }
参考
- 面向对象设计实践指南: Ruby 语言描述 人民邮电,找最新版本english。
Percent Strings
%() string
%w() Array of string,例子 %w(1 2) => ["1", "2"]
%r() 正则表达式
元编程: define_method
class A
def self.define_my_method(x)
define_method("output_#{x}") do
puts "This is #{x}"
end
end
end
class B < A
define_my_method :foo # 定义 output_foo 方法
end
class C < A
self.define_my_method(:bar) # 完整的写法,类宏
end
B.new.output_foo # 输出 This is foo
C.new.output_bar # 输出 This is bar
在 Rails 很多这样的宣告背后,都是用 define_method
做出来的:
class Firm < ActiveRecord::Base
has_many :clients
has_one :account
belongs_to :user
end
# has_many 是 AciveRecord 的类方法(class method) # 其内容是动态定义出 Firm 的一堆对象方法(instance methods) firm = Firm.find(1)
firm.clients
firm.account
firm.user
直接复写 Class 的定义去修改行为,在 Rails 中常用这招来扩增原本 Ruby 的行为,例如:
blank? 方法。检查对象是否是nil或者空字符串,空数组。
class Object # 在 Ruby 中所有的类都会继承自 Object 这个类
def blank?
respond_to?(:empty?) ? empty? : !self
end
end
[1,2,3].blank? # false"blah".blank? # false"".blank? # truenil.blank? # true
解释:Object#respond_to?(:symbol)是看receiver是否对method回应,返回boolean. 数组和字符串都有empty?方法. nil是个伪变量,没有方法。它的!self就是true