Terry七月Ruby读书笔记(比较详细)第3/4页
复杂数据类型
1. 数组
(1) 建立数组
¨ array_1=[]
¨ array_2=Array.new
¨ array_3=['3 ','4 ','5 ']
(2) 访问元素
arr=[3,4,5,6,7,8,9]
Ruby以整数作为下标,访问数组元素通过数组下标,数组下标称作数组索引比较好一些。
数组的索引从0开始(arr[0]),一直到数组的长度减去1,如:arr[arr.length-1]或arr[arr.size-1]);
负数表示从数组末尾开始的索引,如:arr[-1]。
用一对数字索引数组,第一个数字表示起始位置,第二数字表示从起始位置开始的元素数目。如:arr[2..4],arr[-3,2]。
arr.first,arr.last分别代表第一个和最后一个元素。
(3) 增删元素
Ruby的数组大小是动态的,你能够随时增加、删除数组元素。
print arr.join(", "),"\n" 意思是:将数组 arr转换成字符串输出,用", "隔开每个
元素,并且换行。
arr=[3,4,5]
print arr #输出:345
print arr.join(", ") #输出:3,4,5
(4) 数组运算
arr1=["abc",1,2,"de"]
arr2=[2,3,4,7,6,5]
运算 |
运算表达式 |
输出结果 |
加 |
print arr1+arr2 |
abc12de234765 |
减 |
print arr2-arr1 |
34765 |
乘 |
print arr1*2 |
abc12deabc12de |
并 |
print arr1|arr2 |
abc12de34765 |
交 |
print arr1&arr2 |
2 |
排序 |
print arr2.sort |
234567 |
倒置 |
print arr1.reverse |
de21abc |
2. 字符串
(1) 生成一个字符串
字符串是 String 类的对象,一般使用字符串值来创建。
%q用来生成单引号字符串;
%Q用来生成双引号字符串。
%q或者%Q后面跟着的是分隔符,可以是配对的!!;//;<>;();[];{};等等。
字符串文档,从<<和文档结束符的下一行开始,直至一个放置在行首的文档结束符结束。文档结束符自己指定,结束符本身不属于字符串。
注意:文档结束符后面不能跟有空格。
一个数组可以用join方法转换成字符串,join()内的参数也是一个字符串,用来分隔数组的每个元素,例如:arr.join(",")。
(2) 字符串操作
字符串既然是String类的对象,String类的方法你都可以使用在字符串变量上。
(3) 字符串转义
双引号括起来的字符串会有转义,例如:“\n”表示换行。
单引号括起来的字符串不会转义,有一个例外:单引号字符串里的单引号,需要转义。
(4) 字符串内嵌表达式
在双引号字符串中,不仅可以使用转义符,而且可以在#{ }之中放入Ruby表达式,使用字符串时,这些表达式的值被计算并放入字符串。
字符串内嵌表达式,使得你能够更加灵活地组织代码,表现出更强、更多的动态特性。
3. 代码块
可以用大括号{ }将代码组织成块,也可以用 do…end 将代码组织成块。大括号{ }的优先级高于 do…end。代码块,简称块。
yield [ji:ld] 产生,输出……
注意:{}或者do…end之间的是块。
#E8.4-1.rb def one_block yield yield yield end
|
one_block { puts "This is a block." } |
代码块 |
把块作为参数,带入到def定义中的yield处即可。
调用一次块要用关键字yield。每一次yield,块就被调用一次。
yield还可以带参数调用块,yield后面是实参,块定义处是形参。
一个块可以接收yield传来的参数,还可以将结果返回给调用它的方法。
如果我们还没有决定在块里写什么代码,或者块里的代码会随着不同的情形而变化,那么就看出代码块的灵活性了。
先写出方法的大致框架,调用方法的时候才告诉方法要作什么。
4. 迭代器
迭代器是一个与代码块有关联的方法。
(1..9).each {|i| print i if i<7}
迭代器 each 是数组类的一个方法;大括号{ }里的代码是代码块。
class Array def one_by_one for i in 0...size yield(self[i] ) end puts end end
|
arr = [1,3,5,7,9] arr.one_by_one {|k| print k , ", "} # 1, 3, 5, 7, 9, arr.one_by_one {|h| print h*h, ", "} # 1, 9, 25, 49, 81,
|
5. 闭包
代码块是一段代码,相当于一个匿名方法,被调用它的方法所调用。
如果我们不仅仅想调用代码块,还想把代码块作为参数传递给其它方法,就要使用闭包。
闭包也是一段代码,一个代码块,而且能够共享其它方法的局部变量。
闭包既然是一段代码,也就有自己的状态,属性,作用范围,也就是一个可以通过变量引用的对象,我们称之为过程对象。
一个过程对象用 proc 创建,用 call 方法来调用。
¨ 闭包作为参数传递给其它方法
以下两个程序相同
程序1 |
程序2 |
def method(pr) puts pr.call(7) end
oneProc=proc{|k| k *=3} method(oneProc) |
oneProc=proc{|k| k *=3}
puts oneProc.call(7) |
#过程对象oneProc作为一个参数,传递给method; |
|
¨ 闭包共享其它方法局部变量
def method(n) return proc{|i| n +=i } end
oneProc=method(3) puts oneProc.call(9) #12 puts oneProc.call(5) #17 |
方法method返回一个Proc对象,这个对象引用了函数的参数n。即使参数n在闭包被调用时已经不在自己的作用域里,这个闭包还是可以访问参数n,并且和方法method共同拥有变量n。开始时方法method的变量n是3;oneProc.call(9)的时候,oneProc 更新了变量n,把n=12 传回给方法method;oneProc.call(5)的时候,oneProc取出方法 method 的变量 n=12,更新为n=17,传回给方法method的同时,也把n=17作为自己的返回值输出。 |
正则表达式
正则表达式(regular expression)描述了一种字符串匹配的模式,可以用来检查一个串是否含有某种子串;将匹配的子串做替换;或者从某个串中取出符合某个条件的子串;等等。
Ruby 中,可以使用构造器显式地创建一个正则表达式,也可以使用字面值形式 /正则模式/ 来创建一个正则表达式。
=~ |
匹配一个正则表达式:用来比较是否符合一个正则表达式,返回模式在字符串中被匹配到的位置,否则返回nil。 |
!~ |
不匹配一个正则表达式:用来断言不符合一个正则表达式,返回true,flase。 |
一些字符或字符组合在正则表达式中有特殊的意义。
特别字符 |
描述 |
( ) |
标记一个子表达式的开始和结束位置。子表达式可以获取供以后使用。要匹配这些字符,请使用 \( 和 \)。 |
[] |
范围描述符 (比如,[a - z] 表示在 a 到 z 范围内的一个字母),要匹配 [,请使用\[。 |
{} |
标记限定符表达式。要匹配{,请使用 \{。 |
\ |
将下一个字符标记为或特殊字符、或原义字符、或向后引用、或八进制转义符。例如, 'n'匹配字符 'n'。'\n'匹配换行符。序列 '\\'匹配 "\",而 '\('则匹配 "("。 |
| |
指明两项之间的一个选择。要匹配 |,请使用 \|。 |
. |
匹配除换行符 \n之外的任何单字符。要匹配 .,请使用 \。 |
非打印字符
非打印字符 |
描述 |
\f |
匹配一个换页符。等价于\x0c。 |
\n |
匹配一个换行符。等价于\x0a。 |
\r |
匹配一个回车符。等价于\x0d。 |
\s |
匹配任何空白字符,包括空格、制表符、换页符等等。等价于[\f\n\r\t\v]。 |
\S |
匹配任何非空白字符。等价于[^\f\n\r\t\v]。 |
\t |
匹配一个制表符。等价于\x09。 |
\w |
匹配包括下划线的任何单词字符。等价于'[A-Za-z0-9_]'字母或数字;相当于[0-9A-Za-z] |
\W |
匹配任何非单词字符。等价于'[^A-Za-z0-9_]'非字母,数字 |
\d |
匹配一个数字字符。等价于[0-9]。[0-9]数字;相当于[0-9] |
\D |
匹配一个非数字字符。等价于[^0-9]。非数字字符 |
\b |
退格符(0x08)(仅在范围描述符内部时) |
限定符
限定符用来指定正则表达式的一个给定组件必须要出现多少次才能满足匹配。
* 和 + 限定符都是贪婪的,因为它们会尽可能多的匹配文字,只有在它们的后面加上一个 ? 就可以实现非贪婪或最小匹配。
限定符 |
描述 |
* |
前面元素出现0或多次。* 等价于{0,}。 例如,zo*能匹配 "z"以及 "zoo"。 要匹配 * 字符,请使用 \*。 |
+ |
前面元素出现1或多次。+ 等价于{1,}。 例如,'zo+' 能匹配 "zo" 以及 "zoo",但不能匹配 "z"。 要匹配 + 字符,请使用 \+。 |
? |
前面元素最多出现1次;相当于 {0,1}。 例如,”do(es)?” 可以匹配 “do” 或 “does” 中的"do" 。 要匹配 ? 字符,请使用 \?。 |
{n} |
n 是一个非负整数。匹配确定的 n 次。 例如,'o{2}' 不能匹配 "Bob" 中的 'o',但是能匹配 "food"中的两个o。 |
{n,} |
n 是一个非负整数。至少匹配n 次。'o{1,}' 等价于 'o+'。'o{0,}' 则等价于 'o*'。 例如,'o{2,}' 不能匹配 "Bob"中的 'o',但能匹配 "foooood"中的所有 o。 |
{n,m} |
m 和 n 均为非负整数,其中n <= m。前面元素最少出现n 次,最多出现 m次。 'o{0,1}'等价于 'o?'。请注意在逗号和两个数之间不能有空格。 例如,"o{1,3}"将匹配 "fooooood"中的前三个 o。 |
定位符
用来描述字符串或单词的边界,^和$分别指字符串的开始与结束,\b描述单词的前或后边界,\B表示非单词边界。不能对定位符使用限定符。
定位符 |
描述 |
^ |
匹配输入字符串的开始位置,除非在方括号表达式中使用,此时它表示不接受该字符集合。要匹配^字符本身,请使用\^。 |
$ |
匹配输入字符串的结尾位置。如果设置了RegExp对象的Multiline属性,则$也匹配'\n'或'\r'。要匹配$字符本身,请使用\$。 |
\b |
匹配一个单词边界,也就是指单词和空格间的位置。例如,'er\b'可以匹配"never"中的'er',但不能匹配"verb"中的'er'。 |
\B |
匹配非单词边界。'er\B'能匹配"verb"中的'er',但不能匹配"never"中的'er' |
各种操作符的运算优先级
相同优先级的从左到右进行运算,不同优先级的运算先高后低。各种操作符的优先级从高到低如下:
优先级 |
操作符 |
描述 |
高 |
\ |
转义符 |
|
(),[] |
圆括号和方括号 |
|
*,+,?,{n},{n,},{n,m} |
限定符 |
|
^,$, |
位置和顺序 |
低 |
| |
“或”操作 |
元编程
元编程:编写能够生成程序的程序。
听起来很有趣!
Ruby语言强大的动态特征,赋予了我们灵活地进行元编程的能力。
Ruby语言的访问控制是动态的,是在程序运行时刻确立的。
你可以根据自己的需要,在程序的不同位置,改变某个方法的访问控制级别,让你的程序更加富于变化。
page 79
模块化程序设计
1. 模块
在程序中,相关的、不相关的代码的组合,叫作模块。一般情况下,我们总是把功能相关的代码放在一个模块里。
把功能相关的程序代码放在一个模块里,体现了模块的第一个作用:可以被其它程序代码重复使用。
Ruby标准包里的 Math 模块提供了许多方法
模块名.方法名(参数) |
Math 模块还提供了两个常量,圆周率π 和自然对数底 e,
模块名::常量名 |
定义模块用 module...end 。模块与类非常相似,但是:
A) 模块不可以有实例对象;
B) 模块不可以有子类。
2. 命名空间
模块的第二个作用:提供了一个命名空间(namespace),防止命名冲突。
include 模块名
定义一个模块方法,在方法名前加上模块名和一个点号“.”。
调用一个模块方法,与定义模块方法一样,要在方法名前加上模块名和一个点号“.”。模块方法提供了一个途径,在模块的外部访问模块内部方法,无须 include模块。定义模块常量不需要如此。
3. 糅和(Mix-in)与多重继承
柔和/混合插入/Mix-in
Ruby是单继承,通过Mix-in模块,实现多重继承的优点。
模块的第三个作用:实现了类似多重继承的功能。
通过“<父类名”,一个子类可以得到父类的属性和方法;
通过“include模块名”,一个子类可以得到某个模块的常量和方法。
类不能被include。
include方法为一个类的所有对象包含某个模块;
extend方法为一个类的某个对象包含某个模块(联系单例方法)。
4. require和load
require方法包含另一个文件,另一个文件名需要是一个字符串。
load方法与require方法相对应,也用来包含另一个文件。
require包含文件,只加载一次,遇到同一文件时自动忽略;不同路径下的同名文件会多次加载。
load包含文件,加载多次,即使是相同路径下同一文件。
总结一下:
require,load |
包含文件 |
include,extend |
包含模块 |
require |
加载文件一次 |
加载文件时可以不加后缀名 |
一般情况下用于加载库文件 |
load |
加载文件多次 |
加载文件时必须加后缀名 |
用于加载配置文件 |
利用load多次加载文件的特性,可以用来实现程序的无缝升级和系统的热部署。程序功能改变了,你只需要重新load一次,其它代码与它再次交互的时候,这个程序实际上已经不是原来的程序了。
page 88
相关文章
mac os gem安装json出现error failed的解决办法
这篇文章主要介绍了mac os gem安装json出现error failed的解决办法,系统是mac os Mavericks,失败提示Failed to build gem native extension,需要的朋友可以参考下2014-06-06Ruby on rails安装后去掉DL is deprecated,please use Fiddle警告信息的方法【
这篇文章主要介绍了Ruby on rails安装后去掉DL is deprecated,please use Fiddle警告信息的方法,通过针对Ruby on rails安装文件中的警告部分源码进行注释来达到消除警告的目的,需要的朋友可以参考下2017-02-02
最新评论