A language that doesn’t affect the way you think about programming is not worth knowing — Alan Perlis |
Item #10
按照Ruby的习惯
类名: ClassNames
方法名: method_names
变量名: variable_names
询问型方法名: methods_asking_a_question?
稍微有些危险的方法: slightly_dangerous_methods!
实例变量: @instance_variables
全局变量: $global_variables
常量: SOME_CONSTANTS 或者 OtherConstants
这些习惯中,有一些是Ruby语言强制要求的,而另外一些是Ruby社区的习惯。
Item #9
一切都是对象
所有的可以跟变量名字绑定的内容都是完整的对象,例如:
首先Classes是对象,例如:如下代码:
def create_from_factory(factory)
factory.new
end
obj = create_from_factory(Array
obj是一个长度为0的数组
int也是对象,例如:
0.zero? # => true
1.zero? # => false
1.abs # => 1
-1.abs # => 1
1.methods # => list of methods for object 1
2.+(3) # => 5 (same as 2+3)
10.class # => Fixnum
(10**100).class # => Bignum
nil也是对象
a = nil
a.nil? # => true
a.methods # => list of methods
a.abs # => NoMethodError
Item #8
几乎所有的东西都是消息(Message)。
string.index("x")
发送消息 :index 带有参数“x”
string.length
发送消息 :length 不带参数
run_status_reports
发送消息 :run_status_reports 给自己
1 + 2
发送消息 :+ 给对象1,同时携带参数 2
array[i]
发送消息 :[] 给参数array,带有参数i
看看这个VCR类
class VCR
def initialize
@messages = []
end
def method_missing(method, *args, &block)
@messages << [method, args, block]
end
def play_back_to(obj)
@messages.each do |method, args, block|
obj.send(method, *args, &block)
end
end
end
VCR类的调用
vcr = VCR.new
vcr.sub!(/Java/) { "Ruby" }
vcr.upcase!
vcr[11,5] = "Universe"
vcr << "!"
string = "Hello Java World"
puts string
vcr.play_back_to(string)
puts string
输出:
Hello Java World
HELLO RUBY Universe!
Item #7
Ruby比你想象的还要动态
反射更容易做到
使用Java动态的创建对象
public static Object create(Class c, String value)
throws Exception
{
Constructor ctor = c.getConstructor(
new Class[] { String.class } );
return ctor.newInstance(
new Object[] { "Hello" } );
}
public static void main (String args[])
throws Exception
{
Greeting g =
(Greeting) create(Greeting.class, "Hello");
g.show();
}
使用Ruby动态的创建对象
def create(klass, value)
klass.new(value)
end
g = create(Greeting, "Hello")
g.show
Greeting是一个class,但是class也是一个对象,所以可以作为参数传递。
开放的类
可以随时给类追加新的方法。
class Integer
def even?
(self % 2) == 0
end
end
p (1..10).select { |n| n.even? }
单例模式(Singleton)
单例模式针对于实例而不是类,例如
class Dog
end
rover = Dog.new
fido = Dog.new
def rover.speak
puts "Red Rover"
end
rover.speak # => "Red Rover"
fido.speak # => NoMethodError
钩子方法
使用钩子方法可以在程序运行的时候跟踪代码对类的修改。
class MyClass
def MyClass.method_added(name)
puts "Adding Method #{name}"
end
def new_method
# Yada yada yada
end
end
输出:
Adding Method new_method
动态代码执行
class Module
def trace_attr(sym)
self.module_eval %{
def #{sym}
printf "Accessing %s with value %s/n",
"#{sym}", @#{sym}.inspect
@#{sym}
end
}
end
end
class Dog
trace_attr :name
def initialize(string)
@name = string
end
end
Dog.new("Fido").name
Item #6
对象是强类型的,但是不是静态类型的。
Item #5
不要管接口
Duck Type
Item #4
使用 Mix-Ins
Item #3
使用闭包
Iteration
[1,2,3].each do |item| puts item end
Resource Management
file_contents = open(file_name) { |f| f.read }
Callbacks
widget.on_button_press { puts "Got Button Press" }
Item #2
使用ri和irb
Item #1
不需要写那么多代码