讀《松本行弘的程序世界》

斷斷續續花了好久才把這本書讀完,內容比較雜,也不是特別深刻,應該是從平常的文章彙總而成,有些內容仍是值得一讀。並且能夠看出做者並無仔細的整理這些內容,關於對象和塊的章節重複和累贅部分不少,關於 Schewarzian Transform 也講了不少次。程序員

1 我爲何開發 Ruby

  • 語言能夠影響說話者的思想;
  • 一個程序員無論他使用什麼編程語言,他在必定時間裏編寫的程序行數是必定的。

2 面向對象

  • 引入有限制的多重繼承應該是一個好方法。
  • 與繼承有關的內容。
用語 內容
單一繼承 只有一個父類,單純但存在幾個問題
多重繼承 多個父類,但引入了單一繼承沒有的新問題
靜態語言(Java) 區分規格繼承和實現繼承
動態語言 只有實現繼承
規格多重繼承的問題 Java 的接口能夠解決
實現多重繼承的問題 Mix-in 能夠解決
Mix-in 全部支持多重繼承的語言均可以考慮使用
Ruby 的 Mix-in 強制使用模塊,來解決多重繼承的問題
  • 靜態語言中能夠實現多態性的只是限於擁有共通父類的對象。
  • 數據要記錄與本身數據類型有關的信息。這樣的數據類型稱爲動態類型。
  • 靜態類型,直接執行,速度快。
  • 動態類型,邊解釋源代碼邊執行速度慢。優勢,靈活性。

3 程序塊

  • C 語言是經過函數指針來把函數做爲一種對象來處理的。
  • 在塊中能夠引用外部局部變量的方法,說明塊不知是簡單的程序代碼,並且把外部「環境」也包括了進來,想這樣的塊稱爲閉包。
  • 在被調用的方法中有兩種方式來使用傳遞來的塊。一種是用「塊參數」的方式明確聲明接受塊做爲參數,另外一種是使用yield這個Ruby的保留詞。
rubydef each(&block)
  i = 0
  while i < self.size
    block.call(self[i])
    i+=1
  end
end
rubydef each()
  i=0
  while i < self.size
    yield self[i]
    i+=1
  end
end

塊做爲參數的優勢:
1. 明確表示了塊處理;
2. 塊和對象同樣被統一處理了;
3. 檢查參數是否爲 nil 就能夠判斷是否傳遞了塊參數。正則表達式

yield 的優勢:
1. 沒有用到閉包,執行速度稍快;
2. 錯誤信息比較用一理解。編程

  • sort_by 用執行的代碼塊生成的結果拍續,對每一個元素只執行一次塊的調用。與其說是比較兩個元素,更多的時候是對每一個元素進行某種處理,用處理的結果來排序。(原來如此)。
  • 用塊來保證程序的後處理。

3.2.5 Enumerable 的侷限

注:這一節很贊。設計模式

Enumerable 的兩個主要缺點:
1. 循環都依賴 each 方法,並且不能並行執行;
2. 從多個對象取出元素進行處理比較難寫。數組

用 Ruby 來定義 zip 方法的話,到目前爲止,由於沒有提供外部迭代器,因此只能在內部把參數變換成數組來對應。把參數做成數組,有如下兩個問題:
1. 大量的數據變換成數組會形成資源的浪費;
2. 不能處理無限循環的 Enumerable。安全

代碼部分:ruby

rubymodule Enumerable
  def zip(*args)
    n = 0
    args = args.map{|a| a.to_a }
    self.each do |x|
      yield [x, *args.map{|a| a[n] }]
      n += 1
    end
  end
end

能夠修改成:閉包

rubymodule Enumerable
  def zip(*args)
    args = args.map{|a| a.enum_for(:each) }
    self.each do |x|
      yield [x, *args.map{|a|
        a.next rescue nil
      }]
     end
   end
end

1) 不要變換成數組,而是用 enum_for 方法變換成以 each 爲基礎的 Enumerator。若是是 Ruby 1.8.7 ,這部分能夠經過調用塊的 each 方法來實現,可是若是這個類沒有 each 方法,可能不返回 Enumerator。因此用 enum_for 方法纔是安全的。
2) 若是參數用數組可能會消耗很大內存。編程語言

4 設計模式

  • 設計模式的本質,並非介紹至今沒有用過的新模式,而是經過給屢屢使用過的模式起一個合適的名字,從而提供了設計時的詞彙。
  • 舊約全書裏記載了巴比倫塔的故事,描寫了人與人之間由於語言不通,而停止了塔的建設,人們紛紛散去的場面。語言的重要性可見一斑。(溝通的重要性)。

5 Ajax

注:建議粗讀,內容有點老,並且也比較淺函數

6 Ruby on Rails

6.2.3 猴子補丁技巧

undef
undef 有把方法定義取消的功能。用 undef 不只能夠取消本類中的方法,也能夠取消父類中的方法。
** remove_method **
remove_method 僅取消本類中的方法。
alias
用 undef 或 remove_method 刪除了之前方法後,別名的方法依然可使用。別以 alias 只是起別名,而是從新定義了一個方法。

7 文字編碼

注:不感興趣能夠跳過。
文字編碼的難度仍是很大的。

8 正則表達式

注:很讚的一章,要比Ruby鎬頭書和元編程介紹的詳細。

貪婪與懶惰
這是一個常常討論的問題,記得加 .*
分組
使用向後引用的時候,由於要在內部保存數據,效率會受影響。若是僅僅爲了分組,而不須要使用向後引用,可使用沒有向後飲用的模式括號(?:)。
錨點

錨點 匹配位置
^ 行首
$ 行尾(若含換行,則是其前面的字符)
\A 字符串頭
\Z 字符串尾(若含換行,匹配前一字符)
\z 字符串尾
\b 詞頭或詞尾([] 外)
(?=) 用模式指定位置
(?!) 用否認模式制定位置

選項

選項 含義
i 不區分大小寫
m 複數行匹配
o 只展開一次
x 無視正則表達式的空格,註釋有效

註釋

ruby/\d{4}-? #year
  \d{1,2}-? #month
  \d{1,2} #day
/x

8.1.7 特殊變量

$& 最後匹配字符串

8.1.9 split 的本質

  • 用固定字符串分割字符串
  • 用正則來分隔
  • 若是不想去掉標籤,而是將其保存下來,能夠用括號將模式包起來。
rubystr = "<ul><li>a</li>b</ul>"
str.split(/(<.*?>)/)
# ["", "<ul>", "", "<li>", "a", "</li>", "b", "</ul>"]

8.1.10 字符串掃描

ruby"afdasfasdfads".scan(/fa./){|s| p s }

下面代碼執行一樣的動做。它不生成無用的數組,效率稍高一點。(誰能告訴我爲何?)

ruby"afdasfasdfads".scan(/fa./).each{|s| p s }

8.1.11 置換

置換字符串

a = 'abbbcd'
a.gsub(/a(b+)/, "#{$1}") #wrong
a.gsub(/a(b+)/, "\1") #wrong
a.gsub(/a(b+)/, "\\1") #right
a.gsub(/a(b+)/, '\1') #right
a.gsub(/a(b+)/, '\\1') #right
a.gsub(/a(b+)/){ $1 } #right

竟然'\1'和'\1'均可以!

相關文章
相關標籤/搜索