天天看點

Rails源碼筆記-ActiveSupport-core_ext-array

ActiviSupport中包含一些工具類,以及一些對标準類庫的擴充。

ActiveSupport的内容都是是獨立于rails的,是以也可以在非rails的ruby項目中使用。

擷取代碼

使用git clone指令可以将代碼擷取到本地。

git clone git://github.com/rails/rails.git 

我們先從對标準類庫的擴充入手,看看ActiveSupport對ruby的标準類庫都進行了哪些擴充。

擴充都放在activesupport/lib/active_support/core_ext目錄。

進入目錄,機會發現rails對ruby的一些基礎資料類型都進行了擴充。

進入array檔案夾,這裡放的是對array的一些擴充。

打開第一個檔案,access.rb,看看都做了什麼擴充。

class Array 

  # Returns the tail of the array from +position+.  

  #  

  #   %w( a b c d ).from(0)  # => ["a", "b", "c", "d"]  

  #   %w( a b c d ).from(2)  # => ["c", "d"]  

  #   %w( a b c d ).from(10) # => []  

  #   %w().from(0)           # => []  

  def from(position)  

    self[position, length] || []  

  end 

  # Returns the beginning of the array up to +position+.  

  #   %w( a b c d ).to(0)  # => ["a"]  

  #   %w( a b c d ).to(2)  # => ["a", "b", "c"]  

  #   %w( a b c d ).to(10) # => ["a", "b", "c", "d"]  

  #   %w().to(0)           # => []  

  def to(position)  

    first position + 1  

  # Equal to <tt>self[1]</tt>.  

  #   %w( a b c d e).second # => "b"  

  def second  

    self[1]  

  # Equal to <tt>self[2]</tt>.  

  #   %w( a b c d e).third # => "c"  

  def third  

    self[2]  

  # Equal to <tt>self[3]</tt>.  

  #   %w( a b c d e).fourth # => "d"  

  def fourth  

    self[3]  

  # Equal to <tt>self[4]</tt>.  

  #   %w( a b c d e).fifth # => "e"  

  def fifth  

    self[4]  

  # Equal to <tt>self[41]</tt>. Also known as accessing "the reddit".  

  def forty_two  

    self[41]  

end 

你會發現rails的代碼很清晰,而且代碼中的注釋詳細而不羅嗦,除去解釋方法的用途,一般都會有幾個簡單的例子,很實用。

這裡我将這個檔案的全部内容都貼了出來,以後可能會酌情調整,如果有裁剪,大家可以去clone源碼,自己對照檢視。

關于ruby的api,給大家推薦兩個地方。

<a href="http://ruby-doc.org/core-1.9.3/">http://ruby-doc.org/core-1.9.3/</a>

一個是官方的網站,很完整,很全面。

<a href="http://apidock.com/">http://apidock.com/</a>

一個是api筆記網站,任何注冊的使用者都可以在任何一個api下面添加筆記,挺有意思的。而且不僅包含ruby,還有rails和rspec。

擴充了7個方法

from(position)

傳回從給出的位置到末尾的子數組。英文的解釋其實更貼切,return  the tail of the array from +position+。從position的位置傳回資料的尾巴。

to(position)

和from相反,是從頭到position的子數組。

還擴充了second, third, fourth, fifth, forty_two,分别用來傳回資料的第二個,第三個,第四個,第五個,第41個元素。

我們再來看看array檔案夾中的第二個檔案conversions.rb。

這個檔案中定義的擴充,主要功能是類型轉換。

to_sentence(options = {})

将數組元素用逗号連接配接成一個句子,最後兩個元素使用連接配接詞連接配接。

可以将數組變成一個句子,預設使用逗号和and連接配接,包含可選的hash參數options,在參數中可以指定連接配接數組元素的符号,兩個元素的情況下如何連接配接,多個單詞的情況下最後兩個如何連接配接,等等。

to_formatted_s(format =&gt; :default)

将元素的to_s方法傳回的結果連接配接成字元串。指定了:db參數之後,結果就變成了用逗号連接配接對象的id。

定義别名,to_default_s是to_s的别名。

alias_method :to_default_s, :to_s

alias_method :to_s, :to_formatted_s

關于上面這種用法,我來解釋一下,在rails的源碼中會多次的遇到。

意思就是先給to_s起了一個别名to_default_s,然後給to_s起了一個别名to_formatted_s。

怎麼了解呢,我們先看個例子吧。

class Person 

  def getName 

    puts "andyshi" 

  def getName_new 

    puts "before" 

    getName_old 

    puts "after" 

  alias_method :getName_old, :getName 

  alias_method :getName, :getName_new 

p=Person.new 

p.getName 

我們發現輸出的結果是

before 

andyshi 

after 

經過兩行的alias_method,對于調用的用戶端來說,不需要修改,還是繼續調用getName,但是結果發生了變化,前後都加入了新結果。有點aop的效果。

詳細解釋一下。

首先給原來的getName重命名getName_old,然後定義一個getName_new方法,裡面加入其他内容,然後調用getName_old,相當于調用原來的getName,然後将getName指向getName_new。

以前調用getName的地方不用修改,以後也可以繼續使用getName,但是調用産生的效果發生了變化。

to_xml(options = {})

傳回數組的xml格式字元串。

再來看看另外一個檔案extract_options.r。

這裡面有兩個擴充。

一個是針對hash的。

extractable_options?

傳回對象是否可以抽取。是給array的擴充使用的,下面就會介紹到。

一個是針對array的

extract_options!

如果數組的最後一個元素是可抽取的,也就是最後一個元素是否hash,如果是就傳回這兒元素,否則就傳回一個空的hash,也就是{}。這裡面判斷是否可抽取,就用到了上面介紹的針對hash的擴充。

再來看grouping.rb檔案。

這裡面有三個擴充,都是對array的擴充。

in_groups_of(number, fill_with = nil)

就是将數組分組,每組的個數是number,空位使用fill_with來填充。比如說數組長度是10,指定每組3個元素,這樣第四組隻有一個元素,剩下兩個空位,使用fill_with來填充。

in_groups(number, fill_with = nil)

也是将數組分組,number是分組的個數,就是組的個數,空位使用fill_with填充。

splite(value = nil, &amp;block)

将數組分割成子數組,分割的标志是元素的值等于value的值,或者是block指定的條件。

檔案prepend_and_append.rb

起了兩個别名。

alias_method :append, :&lt;&lt;

alias_method :prepend, :unshift

檔案uniq_by.rb

uniq_by(&amp;block)

根據block中的定義傳回一個新的唯一的數組。

uniq_by!(&amp;block)

和uniq_by功能一樣,但是傳回的是修改之後的自己。

檔案wrap.rb

self.warp(object)

将object包裝成一個數組,如果是數組就直接直接傳回object。

上面就是array檔案夾中的全部内容。

本文轉自 virusswb 51CTO部落格,原文連結:http://blog.51cto.com/virusswb/1082531,如需轉載請自行聯系原作者