Ruby in ruby: my keynote on effective ruby
effective ruby
- 0 表示true,与C++相反;
- 常量应该总是调用freeze方法,这样可以在值异常改变时抛出异常;
- variable shadowing:同一作用域定义两个名称相同的变量;
- module模块也是对象,是特定类的一个实例。类是Class类的实例,模块是Module类的实例。(模块没有new方法,语法更严格);
- 通过include蒋模块引入类,类似于java 接口;
- Ruby singleton class是继承链中匿名且不可见的类,在引入模块时插入。
- initialize不会自动调用父类的super方法。需要自己主动调用,才能初始化父类。
- 尝试使用Struct代替Hash保存结构化数据(待试验)
- ruby equals?检查object_id以确认是同一个对象,值相等也会返回错误。用“==”检查值是否相等;
- 实现比较 借助: “< = >”,接收者小时应当返回“-1”。
- protected必须在父类中定义,然后才可以在两个子类间调用。
- clone方法与dup的对比:(1)clone会携带冻结与否的状态;(2)clone会复制单例类。多数情况我们需要的是dup。 在集合中,二者都是浅拷贝。
- Ruby中参数按引用传递,只有Fixnum类是例外。
Array(nil) # ⇒ []
Array[{a: 3, b: 4}] #=> => [{:a=>3, :b=>4}]
- 如果需要有序集合,使用SortedSet(标准库);
- Reduce: (另作 inject) 【重点】
def sum(enum)
enum.reduce(0) do |accumulator, e|
accumulator + e # returned new accumulator
end
end
- 注意迭代器每次丢弃旧的累加器,所以不存在赋值;
- 累加器的初始值可以忽略,此时以第一个值为原始值并从第二个元素迭代。警告:如果enum为空,则返回nil!
应当学习使用reduce取代下列情况:
hash = {}
array.each {|e| hash[e]=true }
array.reduce({}) {|h, e| h[e]=true } # improved!
Hash.new(DEFAULT_VALUE_LITERAL_HERE)
#这里default value是共享的,危险!- Forwardable moduel可以使委托变容易,是标准库单不是核心库,所以需要引入。【待学习】
- 不要使用字符串直接构造异常对象,要使用异常类,以Error结尾的自定义类。
- 使用ensure管理资源
class Lock
def self.acquire
lock = new
lock.exclusive_lock!
yield(lock) # to block
ensure
lock.unlock if lock
end
end
# equivalent to
Lock.acquire do |lock|
# Exception raiseable here
end
- 避免在ensure 中return
- throw 和catch搭配,类似于goto语句。(感觉不宜使用)
- ruby taint, untaint, freeze方法学习
- class « self ; ###; end 打开类
define_method
prior tomethod_missing
- it’s better to implement
respond_to_missing?
- it’s better to implement
eval
执行的作用域可以被替代,用binding
带出去。
def my_method
x = "I'm in a __#{method__.to_s}"
binding
end
x = "I'm in a scope"
eval(x) #=> I'm in a scope
eval(x, my_method) #=> I'm in a my_method
instance_eval
是单例方法,仅针对当前实例;
- 可以用
obj.ancestors
看继承链。prepend
将模块插入接受者之前。 - MiniTest::Mock.new ( test doubles in RSpec)
- mock.verify check if mocked method called
- Mocha: can clean any change caused by test
- 将字面量移除循环
- 会反复创建对象
- 要冻结字面量并传导到子元素
ary.map(&:freeze).freeze
str.strip
remove spaces around stringstr.chomp
remove trailing separator of string- Gem pry:
cd Array
;ls
- In irb,
irb ${CLASS_NAME}
to open new context andself
will be theCLASS_NAME
.jobs
can show current contexts,fg ${JOB_ID}
to switch.exit
to exit.