参考手册:Ruby的语法——操作符表达式

例:

1+2*3/4

为了便于编程,有些方法调用和控制结构是以操作符的形式出现的。php?name=Ruby" onclick="tagshow(event)" class="t_tag">Ruby语言中有下列操作符。

高  ::
   []
   +(单项) ! ~
   **
   -(单项)
   * / %
   + -
   << >>
   &
   | ^
   > >= < <=
   <=> == === != =~ !~
   &&
   ||
   .. ...
   ?条件操作符)
   =(+=, -= ... )
   not
低  and or

左侧的“高”和“低”表示操作符的优先度。例如“&&”的优先度要高于“||”,所以

a && b || c #=> (a && b) || c
a || b && c #=> a || (b && c)

大部分操作符都是些特殊形式的方法调用,但有的操作符被嵌入语言之中,无法进行再定义。

  *

  可再定义的操作符(方法):

  +@, -@表示单项操作符+, -,在方法定义等场合中可以使用这种表示法。

  | ^ & <=> == === =~ > >= < <= << >>
  + - * /  % ** ~ +@ -@ [] []= `

  *

  不可再定义的操作符(控制结构):

  由多个操作符组合而成的计算赋值操作符、“!=”以及“!~”是不能再定义的。

  = ?: .. ... ! not && and || or ::

赋值

例:

foo = bar
foo[0] = bar
foo.bar = baz

语法:

变量 '=' 表达式
常数 '=' 表达式
表达式`['expr..`]' '=' 表达式
表达式`.'标识符 '=' 表达式

我们使用赋值表达式向变量等对象进行赋值。赋值也可以用作局部变量和常数的声明。赋值表达式的左边必须是下列之一。

  *

  变量

  变量 `=' 表达式

  若左边是变量的话,就将表达式的计算值代入其中。
  *

  数组调用

  表达式1`[' 表达式2 ... `]' `=' 表达式n

  先计算表达式1得到一个对象,再把从表达式2到表达式n之间的这些表达式作为参数,来调用该对象的"[]="方法。

  例:

  class C
   def initialize
    @ary = [0,1,2,3,4,5,6,7]
   end
   def [](i)
    @ary[i * 2]
   end
   def []=( i, v )
    @ary[i * 2] = v
   end
  end
  c = C.new
  p c[3]  # 变成 c.[]( 3 ), 结果为6
  p c[3] = 1 # 变成 c.[]=(3,1),结果为1

  *

  属性调用

  表达式1 `.' 标识符 `=' 表达式2

  计算表达式1得到一个对象,再以表达式2为参数来调用该对象的"标识符="方法。

  例:

  class C
   def foo
    @foo
   end
   def foo=( v )
    @foo = v
   end
  end
  c = C.new
  c.foo = 5 # 变成 c.foo=( 5 )
  p c.foo  # => 5

  还可以使用 attr 来定义属性。

  例:

  class C
   attr :foo, true
  end
  c = C.new
  c.foo = 5 # 变成 c.foo=( 5 )
  p c.foo  # => 5

计算赋值

例:

foo += 12   # foo = foo + 12
a ||= 1   # 若a为伪或者a尚未定义,就把1赋值给a。初始化时的一种习惯写法。

语法:

表达式1 op= 表达式2  # 表达式1等同于普通赋值表达式左边的部分

op就是下列中的某一个。操作符与=之间不留间隔。

+, -, *, /, %, **, &, |, ^, <<, >>, &&, ||

这种赋值形式等同于

表达式1 = 表达式1 op 表达式2

但是,当op是“&&”或“||”时就会变成

表达式1 op (表达式1 = 表达式2)

这个样子。例如在属性调用时

obj.foo ||= true

就不能解释成

obj.foo = obj.foo || true

而应该是

obj.foo || (obj.foo = true)

这样才对。(根据obj.foo结果的不同,有时就不能调用obj.foo=)
多重赋值

例:

foo, bar, baz = 1, 2, 3
foo, = list()
foo, *rest = list2()

语法:

表达式 [`,' [表达式 `,' ... ] [`*' [表达式]]] = 表达式 [, 表达式 ... ][`*' 表达式]
`*' [表达式] = 表达式 [, 表达式 ... ][`*' 表达式]

多重赋值是指,在多个表达式以及数组中同时进行的赋值。左边的各个表达式必须是可以被赋值的。若右边只有一个表达式时,则将该表达式的计算值转为数组后,再把数组中的各个元素依次赋值给左边。若右边数组元素的数量超过左边的话,将忽略多余的数组元素。若右边数组元素个数不足的话,将向左边多余的元素中代入nil。

若左边最后一个表达式前带*的话,则将右边多余的元素以数组的形式代入这个带*的表达式中。若右边没有多余元素的话,就把空数组代入其中。

例:

foo, bar = [1, 2]   # foo = 1; bar = 2
foo, bar = 1, 2   # foo = 1; bar = 2
foo, bar = 1    # foo = 1; bar = nil

foo, bar, baz = 1, 2  # foo = 1; bar = 2; baz = nil
foo, bar = 1, 2, 3  # foo = 1; bar = 2
foo  = 1, 2, 3  # foo = [1, 2, 3]
*foo  = 1, 2, 3  # foo = [1, 2, 3]
foo,*bar = 1, 2, 3  # foo = 1; bar = [2, 3]

在多重赋值过程中,若使用括号的话,就可以把数组内含的元素取出来进行赋值。

(foo, bar), baz = [1, 2], 3   # foo = 1; bar = 2; baz = 3

还可以把特殊形式的赋值表达式转化为多重代入。

class C
 def foo=( v )
  @foo = v
 end
 def []=(i,v)
  @bar = ["a", "b", "c"]
  @bar = v
 end
end

obj = C.new
obj.foo, obj[2] = 1, 2  # @foo = 1; @bar = ["a", "b", 2]

若左边以","结尾或"*"后面没有表达式时,将忽略右边多余的元素。

例:

foo,*  = 1, 2, 3  # foo = 1
foo,  = 1, 2, 3  # foo = 1
*   = 1, 2, 3

当您想忽略方法调用中的所有参数时,就可以使用这个"*"(方法调用中的参数在进行交接时,大体遵循多重代入的规则)。

例:

def foo(*)
end
foo(1,2,3)

多重赋值的值变换为右边的数组。
范围表达式

例:

1 .. 20
/first/ ... /second/

语法:

表达式1 `..' 表达式2
表达式1 ` ... ' 表达式2

如果不是出现在条件表达式中的话,它将返回从表达式1到表达式2的范围对象。范围对象是 Range 类的实例。使用"..."生成的范围对象将不包括终点。

若它出现在条件表达式中时,在表达式1变成真之前,它将一直返回伪。接下来,在表达式2返回真之前,它将一直返回真。一旦表达式2变为真,它将重新返回伪。使用".."时,一旦表达式1返回真,马上就会对表达式2进行计算(就象awk)。而使用"..."时,在进行下个计算之前,一直都不会对表达式 2进行计算(就象sed)。
and

例:

test && set
test and set

语法:

表达式 `&&' 表达式
表达式 `and' 表达式

首先计算左边,若结果为真就接着计算右边。"and"操作符的作用相同但优先度更低。

将包含and的表达式传递给某方法的参数时,必须使用双层括号。

p(true && false)  #=> false
p((true and false)) #=> false

or

例:

demo || die
demo or die

语法:

表达式 `||' 表达式
表达式 or 表达式

首先计算左边,若结果为伪就接着计算右边。"or"操作符的作用相同但优先度更低。

将包含or的表达式传递给某方法的参数时,必须使用双层括号。

p(false || true)  #=> true
p((false or true)) #=> true

not

例:

! me
not me
i != you

语法:

`!' 表达式
not 表达式

若表达式值为真就返回伪,若表达式值为伪则返回真。

表达式 `!=' 表达式

等同于!(表达式 == 表达式)。

表达式 `!~' 表达式

等同于!(表达式 =~ 表达式)。

将包含not的表达式传递给某方法的参数时,必须使用双层括号。

p(! false)  #=> true
p((not false)) #=> true

条件操作符

例:

obj == 1 ? foo : bar

语法:

表达式1 ? 表达式2 : 表达式3

根据表达式1的结果,选择返回表达式2或表达式3。它与

if 表达式1 then 表达式2 else 表达式3 end

完全相同。