有一个函数用来去掉字符串中的标点符号和特殊字符,自保留字母,数字,空格。
def to_alphanumeric(s)
s.gsub /[^\w\s]/, ''
end
#unit test
require 'test/unit'
class ToAlphanumericTest < Test::Unit::TestCase
def test_strips_non_alphanumeric_characters
assert_equal '3 the Magic Number', to_alphanumeric('#3, the *Magic, Number* ?')
end
end
class String
def to_alphanumeric
gsub /[^\w\s]/, ''
end
end
#unit test
require 'test/unit'
class StringExtensionsTest < Test::Unit::TestCase
def test_strips_non_alphanumeric_characters
assert_equal '3 the Magic Number', '#3, the *Magic, Number* ?'.to_alphanumeric
end
end
这样的做法会对Ruby 的标准库造成”污染”,也可能造成冲突,应该三思而后行,看下面的例子[替换]:
def replace(array, from, to)
array.each_with_index do |e, i|
array[i] = to if e == from
end
end
#unit test
def test_replace
book_topics = ['html', 'java', 'css']
replace(book_topics, 'java', 'ruby')
expected = ['html', 'ruby', 'css']
assert_equal expected, book_topics
end
按照[打开类]的思想,我们可以把这个方法移植到Array类中去:
class Array
def replace(from, to)
each_with_index do |e, i|
self[i] = to if e == from
end
end
end
#unit test
def test_replace
book_topics = ['html', 'java', 'css']
book_topics.replace('java', 'ruby')
expected = ['html', 'ruby', 'css']
assert_equal expected, book_topics
end
可是测试失败了,我们来看Array 类中所有以"re"大头的方法:
[ ].methods.grep /^re/ # => [:replace, :reject, :reject!, :respond_to?, ...] 。
已经有replace方法了,产生冲突。
使用命名空间可以轻松搞定命名冲突问题:
module Bookworm
class Text
# ...
end
end
一:查找方法,二:执行方法.通过祖先链向上一级一级查找方法,来看一个复杂的例子:
module Printable
def print
#...
end
def prepare_cover
#...
end
end
module Document
def print_to_screen
prepare_cover
format_for_cover
print
end
def format_for_screen
#...
end
def print
#...
end
end
class Book
include Document
include Printable
#...
end
创建了一个对象,并调用print_to_screen()
b = Book.new
b.print_to_screen
根据bug管理系统,这段代码有问题:print_to_screen()方法没有调用正确的print()方法,除此之外没有其他信息。到底调用的是哪个print()方法呢?我们来看看Book的祖先链:
Book.ancestors # => [Book, Printable, Document, Object, Kernel, ...]
Printable在Document前面,所以是调用的Printable的print方法,而本意是调用Document的print方法,所以我们只需让Document的位置在Printable之前:
class Book
include Printable
include Document
#...
end
Book.ancestors # => [Book, Document, Printable, Object, Kernel, …]