Ruby学习笔记(6) - 表达式

  • 在Ruby里面一切都是表达式,就算是if, when这些都是会返回值的表达式。If, while, case这些语句会返回最后执行的表达式的值。
songType = if song.mp3Type == MP3::Jazz
if song.written < Date.new(1935, 1, 1)
Song::TradJazz
else
Song::Jazz
end
else
Song::Other
end
  • 操作符实际上是一个方法,他作用在对应的对象上。因为Ruby所有东西都是对象,所以这个很容易解释,并且我们可以修改默认对象的操作符的运算规则。如下例:
class Fixnum
alias oldPlus +
def +(other)
oldPlus(other).succ
end
end
  • Ruby里面提供了Shell类似的命令表达式语句,也就是执行一个命令,并将命令的stdout作为表达式的返回。他有两种形式,一种是使用backquote(``,和Shell一样),一种是%x后面跟着分割字符。
`dir`.split[34]   	»  	 "lib_singleton.tip"
%x{echo "Hello there"} » "Hello there/n"
  • backquote的执行实际上是将``里面的String当作参数传递给Kernel::`方法。我们也可以override这个方法来改写默认的行为。
  • assignment operator如果左边是一个object attribute的话,我们可以用方法名后面加一个=号来override掉默认的赋值行为。
# 下面的方法中要注意一定要用self来引用instance variable。因为在attribute writer里面,不允许直接因为别的attribute writer。
class Amplifier
def volume=(newVolume)
self.leftChannel = self.rightChannel = newVolume
end
# ...
end
# 然后我们可以这么引用。
a = Amplifier.new
a.volume = 12
  • Ruby支持multiple assignment,也就是同一个assignment表达式对多个变量进行赋值。这个赋值语句是先将=号右边的所有表达式都按顺序evaluate了之后,然后再进行赋值。所以a, b = b, a 这样的语句是可以正常的运行的。
  • 如果想要将multiple assignment的右边的变量collapse成一个array的话,那就在左边的lvalue的前面加上*。同样的,如果想將数组expand掉然后赋值给右边的变量的话,那就在rvalue的数组前面加*。

  • Ruby里面出了nil和false之外,所有的值都为true,包括0和空串。这是需要注意的。
  • Ruby里面有一个define?操作符,可以用来查看一个表达式是什么含义。当后面跟着的是一个没有定义的变量的时候,那么就会返回nil。
  • 关系运算符的定义如下:
Common comparison operators
Operator Meaning
== Test for equal value.
=== Used to test equality within a when clause of a case statement.
<=> General comparison operator. Returns -1, 0, or +1, depending on whether its receiver is less than, equal to, or greater than its argument.
<, <=, >=, > Comparison operators for less than, less than or equal, greater than or equal, and greater than.
=~ Regular expression pattern match.
eql? True if the receiver and argument have both the same type and equal values. 1 == 1.0 returns true, but 1.eql?(1.0) is false.
equal? True if the receiver and argument have the same object id.
  • Ruby的Range可以当作boolean expression。A range such as exp1..exp2 will evaluate as false until exp1 becomes true. The range will then evaluate as true until exp2 becomes true. Once this happens, the range resets, ready to fire again.
  • 如果一个单独一个Regexp当作boolean expression,他会被自动转化成$_ =~/re/。
  • if表达式的否定形式是unless,如下:
# 下面的意思是,如果>180,就不执行下面的语句
unless aSong.duration > 180 then
cost = .25
else
cost = .35
end
  • case表达式是使用===操作符来比较目前每个case的表达式的。而每个built-in的class都定义了===方法。
kind = case year
when 1850..1889 then "Blues" # 当在同一行写when和后面的表达式时,需要加then,这个和if是一样的。
when 1890..1909 then "Ragtime"
when 1910..1929 then "New Orleans Jazz"
when 1930..1939 then "Swing"
when 1940..1950 then "Bebop"
else "Jazz"
end

# Ruby对Class定义了===,他是检测参数是否是目标的类或者是父类。
case shape
when Square, Rectangle
# ...
when Circle
# ...
when Triangle
# ...
else
# ...
end
  • while和until是对相反的循环操作,他也是一个表达式。
# 这个例子需要认真读。首先是||的优先级大于..,所以应该条件表达式应该看成( ($. == 1) || /eig/) .. (($. == 3) || /nin/ )。
# 由于是使用Range当判定条件,所以在开始的时候$.的确是等于1,这个时候range返回true,然后一直到$.等于3的时候,range才开始返回false。
# 然后在下一次到达表达式与/eig/匹配的时候,range则又开始返回真,知道下一次与/nin/匹配之后,才又开始返回false。
file = File.open("ordinal")
while file.gets
print if ($. == 1) || /eig/ .. ($. == 3) || /nin/
end
  • 当while和until modifier用在begin ... end block的后面的时候,这个block至少会被执行一次。
  • 在Ruby里面,更鼓励使用iterator来做循环,比如下面的例子:
3.times do 
prints "Ho! "
end
  • for ... in .. 语句实际上是一个syntatic sugar,他会被转化成一个each iterator。唯一的不同是局部变量的作用域。
for aSong in songList
aSong.play
end

# 会被转化成
songList.each do |aSong|
aSong.play
end

# 注意只要类里面定义了each方法,那么就可以使用for in语句
  • break和next和C里面的break和continue有一样的功能。redo是重新开始这一轮的循环,而不是进入下一轮。而且这3个语句可以用在iterator里面。
  • retry是重新开始一个循环。
for i in 1..100
print "Now at #{i}. Restart? "
retry if gets =~ /^y/i
end
  • Scope: while, until, for是Ruby的built-in的语法,所以他的scope是和包含他的scope融合在一起的,也就是说在这些block里面定义的变量在循环结束 了之后也可以正常的使用。而在iterator里面用的code block里面定义的变量则不能在外面使用,不过如果变量名是已经存在的变量的话,那么就会使用这个存在的变量,包括参数也是这样。可以看下面的例子:
x = nil
y = nil
[ 1, 2, 3 ].each do |x|
y = x + 1
end
[ x, y ] » [3, 4]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值