ActiviSupport中包含一些工具类,以及一些对标准类库的扩展。
ActiveSupport的内容都是是独立于rails的,因此也可以在非rails的ruby项目中使用。
获取代码
rails的源码位于https://github.com/rails/rails。
使用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
- end
- # Equal to <tt>self[1]</tt>.
- #
- # %w( a b c d e).second # => "b"
- def second
- self[1]
- end
- # Equal to <tt>self[2]</tt>.
- #
- # %w( a b c d e).third # => "c"
- def third
- self[2]
- end
- # Equal to <tt>self[3]</tt>.
- #
- # %w( a b c d e).fourth # => "d"
- def fourth
- self[3]
- end
- # Equal to <tt>self[4]</tt>.
- #
- # %w( a b c d e).fifth # => "e"
- def fifth
- self[4]
- end
- # Equal to <tt>self[41]</tt>. Also known as accessing "the reddit".
- def forty_two
- self[41]
- end
- end
你会发现rails的代码很清晰,而且代码中的注释详细而不罗嗦,除去解释方法的用途,一般都会有几个简单的例子,很实用。
这里我将这个文件的全部内容都贴了出来,以后可能会酌情调整,如果有裁剪,大家可以去clone源码,自己对照查看。
关于ruby的api,给大家推荐两个地方。
http://ruby-doc.org/core-1.9.3/
一个是官方的网站,很完整,很全面。
http://apidock.com/
一个是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 => :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。
怎么理解呢,我们先看个例子吧。
|
- 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, &block)
将数组分割成子数组,分割的标志是元素的值等于value的值,或者是block指定的条件。
文件prepend_and_append.rb
起了两个别名。
alias_method :append, :<<
alias_method :prepend, :unshift
文件uniq_by.rb
uniq_by(&block)
根据block中的定义返回一个新的唯一的数组。
uniq_by!(&block)
和uniq_by功能一样,但是返回的是修改之后的自己。
文件wrap.rb
self.warp(object)
将object包装成一个数组,如果是数组就直接直接返回object。
上面就是array文件夹中的全部内容。