Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Ruby / Yukihiro Matsumoto_Programming Ruby.doc
Скачиваний:
121
Добавлен:
06.06.2015
Размер:
2.71 Mб
Скачать

Parallel Assignment

During your first week in a programming course (or the second semester if it was a party school), you may have had to write code to swap the values in two variables:

int a = 1;

int b = 2;

int temp;

temp = a;

a = b;

b = temp;

You can do this much more cleanly in Ruby:

a, b = b, a

Ruby assignments are effectively performed in parallel, so the values assigned are not affected by the assignment itself. The values on the right-hand side are evaluated in the order in which they appear before any assignment is made to variables or attributes on the left. A somewhat contrived example illustrates this. The second line assigns to the variables a,b, andcthe values of the expressionsx,x+=1, andx+=1, respectively.

x = 0

»

0

a, b, c   =   x, (x += 1), (x += 1)

»

[0, 1, 2]

When an assignment has more than one lvalue, the assignment expression returns an array of the rvalues. If an assignment contains more lvalues than rvalues, the excess lvalues are set to nil. If a multiple assignment contains more rvalues than lvalues, the extra rvalues are ignored. As of Ruby 1.6.2, if an assignment has one lvalue and multiple rvalues, the rvalues are converted to an array and assigned to the lvalue.

You can collapse and expand arrays using Ruby's parallel assignment operator. If the last lvalue is preceded by an asterisk, all the remaining rvalues will be collected and assigned to that lvalue as an array. Similarly, if the last rvalue is an array, you can prefix it with an asterisk, which effectively expands it into its constituent values in place. (This is not necessary if the rvalue is the only thing on the right-hand side---the array will be expanded automatically.)

a = [1, 2, 3, 4]

b,  c = a

»

b == 1,

c == 2

b, *c = a

»

b == 1,

c == [2, 3, 4]

b,  c = 99,  a

»

b == 99,

c == [1, 2, 3, 4]

b, *c = 99,  a

»

b == 99,

c == [[1, 2, 3, 4]]

b,  c = 99, *a

»

b == 99,

c == 1

b, *c = 99, *a

»

b == 99,

c == [1, 2, 3, 4]

Nested Assignments

Parallel assignments have one more feature worth mentioning. The left-hand side of an assignment may contain a parenthesized list of terms. Ruby treats these terms as if they were a nested assignment statement. It extracts out the corresponding rvalue, assigning it to the parenthesized terms, before continuing with the higher-level assignment.

b, (c, d), e = 1,2,3,4

»

b == 1,

c == 2,

d == nil,

e == 3

b, (c, d), e = [1,2,3,4]

»

b == 1,

c == 2,

d == nil,

e == 3

b, (c, d), e = 1,[2,3],4

»

b == 1,

c == 2,

d == 3,

e == 4

b, (c, d), e = 1,[2,3,4],5

»

b == 1,

c == 2,

d == 3,

e == 5

b, (c,*d), e = 1,[2,3,4],5

»

b == 1,

c == 2,

d == [3, 4],

e == 5

Other Forms of Assignment

In common with many other languages, Ruby has a syntactic shortcut: a=a+2may be written asa+=2.

The second form is converted internally to the first. This means that operators that you have defined as methods in your own classes work as you'd expect.

class Bowdlerize

  def initialize(aString)

    @value = aString.gsub(/[aeiou]/, '*')

  end

  def +(other)

    Bowdlerize.new(self.to_s + other.to_s)

  end

  def to_s

    @value

  end

end

a = Bowdlerize.new("damn ")

»

d*mn

a += "shame"

»

d*mn sh*m*

Соседние файлы в папке Ruby