書中原始碼是這樣的
File.foreach('1.txt') do |x| if(($. == 1) || x =~ /eig/) .. (($. == 3) || x =~ /nin/) then print x end end
其中 1.txt內容如下
first
second
third
fourth
fifth
sixth
seventh
eigth
ninth
tenth
按道理 讀取第一行的first,$.應該是1 ($.是一個全域性變數,表示行號)但是rubymine調式發現不是1,這個我暫時沒找到原因。所以經別人提示。我改成這樣
f = File.new('1.txt') f.each do |line| if ((f.lineno == 1) || line.chomp =~ /eig/)..((f.lineno== 3) || line.chomp =~ /nin/) then print f.lineno print line end end
這樣 f.lineno表示每次讀取的行號 執行測試結果如下
書上只提到2點,
1 exp1..expr2這樣的rang, 在exp1變為真之前,它的值為假,在exp2變為真正之前,rang被求解為真
2 這段程式碼片段。就是列印1到3行及位於/eig/和/nin/之間
有點晦澀難懂,然後群裡有人提示,看這個文章: http://nithinbekal.com/posts/ruby-flip-flop/
The flip flop operator is a range (..
) operator used between two conditions in a conditional statement. It looks like this:
(1..20).each do |x| puts x if (x == 5) .. (x == 10) end
The condition evaluates to false every time it is evaluated until the first part evaluates to true. Then it evaluates to true until the second part evaluates to true. In the above example, the flip-flop is turned on when x == 5
and stays on until x == 10
, so the numbers from 5 to 10 are printed.
(x == 5) .. (x == 10) 這個東西叫做flip flop
1 藍色英文就是說,當第一部分也就是(x==5)為真的時候。整個if判斷為真,但是什麼時候為假呢。直到第二部分為真也就是(x==10)時候, 也就是前面提到的 exp1..expr2這樣的rang, 在exp1變為真之前,它的值為假,在exp2變為真正之前,rang被求解為真 2 紅字英文意思就是 x==5時,這個表示式開始執行。什麼時候停止呢,知道x==10,所以列印5到10之間
所以理解
((f.lineno == 1) || line.chomp =~ /eig/)..((f.lineno== 3) || line.chomp =~ /nin/)
可以這麼想,當f.lineno 值為1的時候 這個表示式 ((f.lineno == 1) || line.chomp =~ /eig/) 為真,整個if 為真,
然後列印 1first,什麼時候列印終止?,當flineno=3或者line.chomp(chomp去掉行尾的/r/n)的值匹配/nin/,他們兩個滿足其中一個的時候 就不列印了。
可以像下面程式碼這樣理解
f = File.new('1.txt') f.each do |line| if ((1..3).include?f.lineno) or (line =~ /eig/ or line =~ /nin/) then print f.lineno print line end end