这两天有空学习下Ruby,以下简单记录Ruby的一些关键信息。
基本语法
==、equal?
== 比较两个变量的值是否相等;equal?比较的是内存地址。和Java刚好相反。
if
if...end
if...elsif...end
if...else...end
条件判断if可以有两种写法,多条语句时:
if condition
#do something
end
单条语句时:
#do something if condition
case
case when condition1 ... when ...end
case功能类似于c或者java中的switch,但是更强大
i=5
case i
when 1
puts "1"
when 2...6
puts "2~5"
end
以上代码会输出2~5。在case中使用操作符“===”比较分支,由于Ruby是完全面向对象的程序语言,所以根据分支数据的不同类型===表现出不同的行为。
while
while...redo...next...break...end
while支持四种打破循环的方法:
- condition 当条件不满足时退出。
- next 等于Java中的continue,结束以下语句直接执行下一次迭代。
- redo 忽略以下语句,但是不进行条件判断再次从头执行本次迭代。
- break 跳出循环
C语言描述:
while (condition) {
label_redo:
goto label_next; /* ruby's "next" */
goto label_break; /* ruby's "break" */
goto label_redo; /* ruby's "redo" */
...
...
label_next:
}
label_break:
...
for
for...in...
for num in collection
puts num
end
each
除了使用循环,还可以直接用each对colleciton、array进行迭代
arr=[1,2,3]
arr.each{|num| puts num}
或者是:
arr=[1,2,3]
arr.each do |num|
num*=2
puts num
end
作用域级别
说法可能不妥,只是个人理解。从大到小Ruby可分为Module、Class、method、procedure(block)。
Module
- Module不能被继承。
- Module不能实例化。
Ruby官方指明Module有两个用处:一个Module可以用于封装一系列功能相关的函数,比如Math;另一个则是通过mixin技术实现Ruby class行为的多重继承:
module TALK
def talk
puts "talk ... talk .."
end
end
class Person
include TALK
end
person=Person.new
person.talk
除此以外,个人觉得Module 类似于Java中的Package,实现了Class命名空间的隔离。
Class
和其他面向对象语言中Class的含义一样,是一类对象共同特征的抽象。Class只能单一继承。
在Ruby中class也是一个对象,其父类是Module,所有对象的根父类都是Object。
super关键字可用于继承关系中调用父方法:
Class Person
def talk
#...
end
end
Class SubPerson < Person
def talk
super
#...
end
end
class_eval关键字可以实现动态的修改、增加class的行为,代码忽略。
Method
method可以在class内外声明,在class外直接声明的method更像脚本语言中的function,而在class中声明的方法则等同于Java语言中的method,可以被class的实例使用。
在method中通过关键字self可以获得方法接受者(receiver)。
除此以外,还有一类特殊的单例方法singleton_method,这里并非设计模式的单例方法。而是指分配给某个但是实例的方法,以下代码中talk_loudly是personA的singleton_method,因为它只属于personA,其他Person实例是无法获得此特性的。
class Person
def talk
#...
end
end
personA=Person.new
def personA.talk_loudly
#...
end
Procedure
Ruby中强大的地方还在于可以直接传递代码块(block),在本质上procedure等于block,只是block是匿名的只能被传递一次,重复使用需要多次书写相同代码;由于Ruby面向对象的特征block也是一个对象,将其赋值给一个变量就成为了procedure可以被重复使用。
block的声明方式可以用do...end(多行)和{}(单行)两种。
yield关键字,要实现each方法的功能,ruby实际上使用了yield关键字,如果一个方法在调用时被隐含传递了block(method(arg) {}),则在方法内调用yield会执行其内容:
def method(name)
if block_given?
puts yield name
else
puts "Hello, #{name}"
end
end
#output Hello, gangzz
method("gangzz")
#output Hey, gangzz
method("gangzz") {|n| puts "Hey, #{n}"}
Singleton_method的几种实现方式
-
def关键字
class Person def talk #... end end personA=Person.new def personA.talk_loudly #... end
-
class<<Instance的方式
class Person def talk #... end end personA=Person.new class<< personA def talk_loudly #... end end
-
instance_eval
class Person def talk #... end end personA=Person.new personA.instance_eval "def talk_loudly;#...;end"
Varialbe
Ruby支持四种不同表示方式的变量:
- $ 全局变量,慎用
- @ 实例变量,作用域为当前实例。
- [a-z] or _ 本地变量,作用域限于方法或者procedure。
- [A-Z] 常量
accessor
读取和修改Class属性的语法糖?
<table border="1"> <tbody> <tr><td><em> Shortcut </em> </td><td> <em> Effect </em> </td></tr> <tr><td> <code> attr_reader :v </code> </td><td> <code> def v; @v; end </code> </td></tr> <tr><td> <code> attr_writer :v </code> </td><td> <code> def v=(value); @v=value; end </code> </td></tr> <tr><td> <code> attr_accessor :v </code> </td><td> <code> attr_reader :v; attr_writer :v </code> </td></tr> <tr><td> <code> attr_accessor :v, :w </code> </td><td> <code> attr_accessor :v; attr_accessor :w </code></td></tr></tbody></table>
Exception
异常的处理,如果运行时参数或状态不正确可以通过raise XXX.new抛出异常,通过以下机制捕获和处理异常。
begin
#...
rescue
#...
ensure
#...
Symbol
通过:name的方式就可以声明一个symbol,和String完全不同在一个Ruby程序的执行过程中相同名字的symbol必然是同一个对象,无论上下文如何变化。Symbol的一个作用是提高效率,因为相比于字符串Symbol仅仅会被创建一次。
http://www.ibm.com/developerworks/cn/opensource/os-cn-rubysbl/index.html