Ruby语法

hel*_*inz 9 ruby

有人为什么我这样写:

ruby-1.8.7-p302 > a = %w( a b c)
 => ["a", "b", "c"] 
ruby-1.8.7-p302 > while (i = a.shift) do; puts i ; end
a
b
c
 => nil 
Run Code Online (Sandbox Code Playgroud)

这看起来像是通过一个块来.并不是:

while(i = a.shift) { puts i; }
Run Code Online (Sandbox Code Playgroud)

是因为while语法的"do"只是语法糖而且与块的"do"无关?

Jör*_*tag 13

难道是因为do该的while语法只是syntaxic糖,如无同做do一个块的?

或多或少,是的.这不是语法糖,它只是一个内置的语言结构,像defclass作为@meagar已经写.

它与do块的无关,除了关键字很昂贵,因此重用关键字是有道理的.("昂贵"我的意思是他们限制程序员的表现力.)

while循环中,有两种方法可以将块与条件分开:

  1. do关键字和
  2. 表达式分隔符.

反过来,Ruby中有两个不同的表达式分隔符:

  1. 分号;
  2. 换行符

因此,以下所有三个都是有效的:

while i = a.shift do puts i end # do

while i = a.shift; puts i end   # semicolon

while i = a.shift
  puts i end                    # newline
Run Code Online (Sandbox Code Playgroud)

[显然,最后一个不会这样写,你会把它end放在一个新的行上,缩小以匹配while.我只是想证明分离while循环部分所需的最小值.]

顺便说一下:将条件放在括号中是非常不恰当的.你的代码中还有很多多余的分号.变量名i通常保留给索引,而不是元素.(我通常el用于泛型元素,但我更喜欢更多的语义名称.)

手动迭代集合也非常不恰当.你的代码写得好得多

a.each(&method(:puts)).clear
Run Code Online (Sandbox Code Playgroud)

不仅更容易理解它的作用(打印数组的所有元素并从中删除所有项),它也更容易编写(没有办法让终止条件错误,或搞砸了任何作业) ).它也恰好更有效:你的版本是Θ(n 2),这个是Θ(n).

实际上,这也不是你怎么写的,因为Kernel#puts无论如何已经实现了这种行为.所以,你真正要写的就是这个

puts a
a.clear
Run Code Online (Sandbox Code Playgroud)

或许这个

a.tap(&method(:puts)).clear
Run Code Online (Sandbox Code Playgroud)

[注意:这最后一个不是100%等效.它打印一个空数组的换行符,所有其他的都不打印.]

简单.明确.简洁.表现力.快速.

比较一下:

while (i = a.shift) do; puts i ; end
Run Code Online (Sandbox Code Playgroud)

我实际上必须多次运行才能100%清楚它的作用.


mea*_*gar 7

while它不是一个块,它是一种语言结构.该do是可选的:

while (i = a.shift)
  puts i
end
Run Code Online (Sandbox Code Playgroud)