Ruby初探

Posted leestar54

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Ruby初探相关的知识,希望对你有一定的参考价值。

官方网站:https://www.ruby-lang.org/zh_cn/
标准库API文档:http://ruby-doc.org/stdlib-2.3.0/

简介

Ruby,一种为简单快捷的面向对象编程(面向对象程序设计)而创的脚本语言,在20世纪90年代由日本人松本行弘(Yukihiro Matsumoto)开发,遵守GPL协议和Ruby License。它的灵感与特性来自于 Perl、Smalltalk、Eiffel、Ada以及 Lisp 语言。Smalltalk 是一个真正的面向对象语言。Ruby,与 Smalltalk 一样,是一个完美的面向对象语言。使用 Ruby 的语法比使用 Smalltalk 的语法要容易得多。由 Ruby 语言本身还发展出了JRuby(Java平台)、IronRuby(.NET平台)等其他平台的 Ruby 语言替代品。Ruby的作者于1993年2月24日开始编写Ruby,直至1995年12月才正式公开发布于fj(新闻组)。因为Perl发音与6月诞生石pearl(珍珠)相同,因此Ruby以7月诞生石ruby(红宝石)命名。在 Ruby 社区,松本也被称为马茨(Matz)。

Ruby 经常位于全球编程语言成长和流行度指数的前十名(比如TIOBE)。造成 Ruby 如此快速成长的原因很大程度上是因为使用 Ruby 编写的 Web 框架 Ruby on Rails 非常受欢迎。

Ruby哲学是:“每一件事情总是有多种做法”(Having more than one way to do the same thing)。
所以程序员的创造力就完全被激发出来了。当你看到某个问题的一种前所未见又十分优雅的解决方案时,你会有一种混杂着强烈喜悦的惊讶的——写(优美的)Ruby能够激发人的灵感。

Ruby的元编程能力还有宽松的语法使得使用Ruby可以很轻松的开发DSL(Domain Specific Language)

Ruby吸收了很多语言(Lisp、Smalltalk等等)的特性,对于程序员来说了解一下Ruby对于开阔思路是很有帮助的,它能帮助你更好的看清你之前一直使用的语言的限制之处在哪。

特性

  • Ruby 是开源的,在 Web 上免费提供,但需要一个许可证。
  • Ruby 是一种通用的、解释的编程语言。
  • Ruby 是一种真正的面向对象编程语言。
  • Ruby 是一种类似于 Python 和 Perl 的服务器端脚本语言。
  • Ruby 可以用来编写通用网关接口(CGI)脚本。
  • Ruby 可以被嵌入到超文本标记语言(html)。
  • Ruby 语法简单,这使得新的开发人员能够快速轻松地学习 Ruby。
  • Ruby 与 C++ 和 Perl 等许多编程语言有着类似的语法。
  • Ruby 可扩展性强,用 Ruby 编写的大程序易于维护。
  • Ruby 可用于开发的 Internet 和 Intranet 应用程序。
  • Ruby 可以安装在 Windows 和 POSIX 环境中。
  • Ruby 支持许多 GUI 工具,比如 Tcl/Tk、GTK 和 OpenGL。
  • Ruby 可以很容易地连接到 DB2、mysql、Oracle 和 Sybase。
  • Ruby 有丰富的内置函数,可以直接在 Ruby 脚本中使用。

安装

linux环境

sudo apt-get install ruby-full # Debian 或 Ubuntu 系统
sudo yum install ruby # CentOS, Fedora, 或 RHEL 系统
ruby -v
ruby 2.1.5p273 (2014-11-13) [x86_64-linux-gnu]

Ruby 命令行选项

Ruby 一般是从命令行运行,方式如下:

$ ruby [ options ] [.] [ programfile ] [ arguments … ]

解释器可以通过下列选项被调用,来控制解释器的环境和行为。

选项 描述
-a 与 -n 或 -p 一起使用时,可以打开自动拆分模式(auto split mode)。请查看 -n 和 -p 选项。
-c 只检查语法,不执行程序。
-C dir 在执行前改变目录(等价于 -X)。
-d 启用调试模式(等价于 -debug)。
-F pat 指定 pat 作为默认的分离模式($;)。
-e prog 指定 prog 作为程序在命令行中执行。可以指定多个 -e 选项,用来执行多个程序。
-h 显示命令行选项的一个概览。
-i [ ext] 把文件内容重写为程序输出。原始文件会被加上扩展名 ext 保存下来。如果未指定 ext,原始文件会被删除。
-I dir 添加 dir 作为加载库的目录。
-K [ kcode] 指定多字节字符集编码。e 或 E 对应 EUC(extended Unix code),s 或 S 对应 SJIS(Shift-JIS),u 或 U 对应 UTF-8,a、A、n 或 N 对应 ASCII。
-l 启用自动行尾处理。从输入行取消一个换行符,并向输出行追加一个换行符。
-n 把代码放置在一个输入循环中(就像在 while gets; … end 中一样)。
-0[ octal] 设置默认的记录分隔符($/)为八进制。如果未指定 octal 则默认为 \0。
-p 把代码放置在一个输入循环中。在每次迭代后输出变量 $_ 的值。
-r lib 使用 require 来加载 lib 作为执行前的库。
-s 解读程序名称和文件名参数之间的匹配模式 -xxx 的任何参数作为开关,并定义相应的变量。
-T [level] 设置安全级别,执行不纯度测试(如果未指定 level,则默认值为 1)。
-v 显示版本,并启用冗余模式。
-w 启用冗余模式。如果未指定程序文件,则从 STDIN 读取。
-x [dir] 删除 #!ruby 行之前的文本。如果指定了 dir,则把目录改变为 dir。
-X dir 在执行前改变目录(等价于 -C)。
-y 启用解析器调试模式。
–copyright 显示版权声明。
–debug 启用调试模式(等价于 -d)。
–help 显示命令行选项的一个概览(等价于 -h)。
–version 显示版本。
–verbose 启用冗余模式(等价于 -v)。设置 $VERBOSE 为 true。
–yydebug 启用解析器调试模式(等价于 -y)。

编码

如果出现乱码或者字符异常,尝试声明编码即可,同时必须设置编辑器保存文件的编码为utf-8。

  1. #!/usr/bin/ruby -w
  2. # -*- coding: UTF-8 -*-
  3. puts "你好,世界!";

语法

让我们编写一个简单的 Ruby 程序。所有的 Ruby 文件扩展名都是 .rb。所以,把下面的源代码放在 test.rb 文件中。

  1. #!/usr/bin/ruby -w
  2. puts "Hello, Ruby!";

$ ruby test.rb
Hello, Ruby!

空白与行尾

在 Ruby 代码中的空白字符,如空格和制表符一般会被忽略,除非当它们出现在字符串中时才不会被忽略。然而,有时候它们用于解释模棱两可的语句。当启用 -w 选项时,这种解释会产生警告。

a + b 被解释为 a+b (这是一个局部变量)
a +b 被解释为 a(+b) (这是一个方法调用)

Ruby 把分号和换行符解释为语句的结尾。但是,如果 Ruby 在行尾遇到运算符,比如 +、- 或反斜杠,它们表示一个语句的延续。

标识符与保留字

标识符是变量、常量和方法的名称。Ruby 标识符是大小写敏感的。这意味着 Ram 和 RAM 在 Ruby 中是两个不同的标识符。
Ruby 标识符的名称可以包含字母、数字和下划线字符( _ )。

下表列出了 Ruby 中的保留字。这些保留字不能作为常量或变量的名称。但是,它们可以作为方法名。
BEGIN do next then
END else nil true
alias elsif not undef
and end or unless
begin ensure redo until
break false rescue when
case for retry while
class if return while
def in self FILE
defined? module super LINE

Here Document

“Here Document” 是指建立多行字符串。在 << 之后,您可以指定一个字符串或标识符来终止字符串,且当前行之后直到终止符为止的所有行是字符串的值。
如果终止符用引号括起,引号的类型决定了面向行的字符串类型。请注意<< 和终止符之间必须没有空格。

  1. #!/usr/bin/ruby -w
  2. # -*- coding : utf-8 -*-
  3. print <<EOF
  4. 这是第一种方式创建here document
  5. 多行字符串。
  6. EOF
  7. print <<"EOF"; # 与上面相同
  8. 这是第二种方式创建here document
  9. 多行字符串。
  10. EOF
  11. print <<`EOC` # 执行命令
  12. echo hi there
  13. echo lo there
  14. EOC
  15. print <<"foo", <<"bar" # 您可以把它们进行堆叠
  16. I said foo.
  17. foo
  18. I said bar.
  19. bar

BEGIN与END 语句

  1. #!/usr/bin/ruby
  2. puts "This is main Ruby Program"
  3. END {
  4. puts "Terminating Ruby Program"
  5. }
  6. BEGIN {
  7. puts "Initializing Ruby Program"
  8. }
  9. Initializing Ruby Program
  10. This is main Ruby Program
  11. Terminating Ruby Program

注释

注释会对 Ruby 解释器隐藏一行,或者一行的一部分,或者若干行。您可以在行首使用字符( # )
或者,注释可以跟着语句或表达式的同一行的后面,
块注释会对解释器隐藏 =begin/=end 之间的行。

  1. # 我是注释,请忽略我。
  2. name = "Madisetti" # 这也是注释
  3. # 这是注释。
  4. # 这也是注释。
  5. # 这也是注释。
  6. # 这还是注释。
  7. =begin
  8. 这是注释。
  9. 这也是注释。
  10. 这也是注释。
  11. 这还是注释。
  12. =end

运算符

Ruby 支持一套丰富的运算符。大多数运算符实际上是方法调用。例如,a + b 被解释为 a.+(b),其中指向变量 a 的 + 方法被调用,b 作为方法调用的参数。
对于每个运算符(+ - * / % ** & | ^ << >> && ||),都有一个相对应的缩写赋值运算符(+= -= 等等)。
逻辑运算符,三元运算符略过,语言通用。

算数运算符

常规语言通用略过
其中 代表指数 - 执行指数计算, 假设变量 a 的值为 10,变量 b 的值为 20, ab 将得到 10 的 20 次方

比较运算符

常规语言通用略过,其中

运算符 描述 实例
<=> 联合比较运算符。如果第一个操作数等于第二个操作数则返回 0,如果第一个操作数大于第二个操作数则返回 1,如果第一个操作数小于第二个操作数则返回 -1。 (a <=> b) 返回 -1。
=== 用于测试 case 语句的 when 子句内的相等。 (1…10) === 5 返回 true。
.eql? 如果接收器和参数具有相同的类型和相等的值,则返回 true。 1 == 1.0 返回 true,但是 1.eql?(1.0) 返回 false。
equal? 如果接收器和参数具有相同的对象 id,则返回 true。 如果 aObj 是 bObj 的副本,那么 aObj == bObj 返回 true,a.equal?bObj 返回 false,但是 a.equal?aObj 返回 true。

赋值运算符

常规语言通用略过,其中
= 指数且赋值运算符,执行指数计算,并赋值给左操作数 c = a 相当于 c = c ** a

并行赋值

  1. a, b, c = 10, 20, 30
  2. #并行赋值在交换两个变量的值时也很有用
  3. a, b = b, c

位运算符

位运算符作用于位,并逐位执行操作。
假设如果 a = 60,且 b = 13,现在以二进制格式,它们如下所示:
a = 0011 1100
b = 0000 1101

a&b = 0000 1100
a|b = 0011 1101
a^b = 0011 0001
~a = 1100 0011

运算符 描述 实例
& 如果同时存在于两个操作数中,二进制 AND 运算符复制一位到结果中。 (a & b) 将得到 12,即为 0000 1100
| 如果存在于任一操作数中,二进制 OR 运算符复制一位到结果中。 (a | b) 将得到 61,即为 0011 1101
^ 如果存在于其中一个操作数中但不同时存在于两个操作数中,二进制异或运算符复制一位到结果中。 (a ^ b) 将得到 49,即为 0011 0001
~ 二进制补码运算符是一元运算符,具有”翻转”位效果。 (~a ) 将得到 -61,即为 1100 0011,2 的补码形式,带符号的二进制数。
<< 二进制左移运算符。左操作数的值向左移动右操作数指定的位数。 a << 2 将得到 240,即为 1111 0000
>> 二进制右移运算符。左操作数的值向右移动右操作数指定的位数。 a >> 2 将得到 15,即为 0000 1111

范围运算符

在 Ruby 中,序列范围用于创建一系列连续的值 - 包含起始值、结束值(视情况而定)和它们之间的值。
在 Ruby 中,这些序列是使用 “..” 和 “…” 范围运算符来创建的。两点形式创建的范围包含起始值和结束值,三点形式创建的范围只包含起始值不包含结束值。
1..10 创建从 1 到 10 的范围
1…10 创建从 1 到 9 的范围

defined? 运算符

defined? 是一个特殊的运算符,以方法调用的形式来判断传递的表达式是否已定义。它返回表达式的描述字符串,如果表达式未定义则返回 nil。

点运算符 “.” 和双冒号运算符 “::”

您可以通过在方法名称前加上模块名称和一条下划线来调用模块方法。您可以使用模块名称和两个冒号来引用一个常量。
:: 是一元运算符,允许在类或模块内定义常量、实例方法和类方法,可以从类或模块外的任何地方进行访问。
请记住:在 Ruby 中,类和方法也可以被当作常量。
您只需要在表达式的常量名前加上 :: 前缀,即可返回适当的类或模块对象。
如果未使用前缀表达式,则默认使用主 Object 类。

  1. CONST = ‘ out there‘
  2. class Inside_one
  3. CONST = proc {‘ in there‘}
  4. def where_is_my_CONST
  5. ::CONST + ‘ inside one‘
  6. end
  7. end
  8. class Inside_two
  9. CONST = ‘ inside two‘
  10. def where_is_my_CONST
  11. CONST
  12. end
  13. end
  14. puts Inside_one.new.where_is_my_CONST
  15. puts Inside_two.new.where_is_my_CONST
  16. puts Object::CONST + Inside_two::CONST
  17. puts Inside_two::CONST + CONST
  18. puts Inside_one::CONST
  19. puts Inside_one::CONST.call + Inside_two::CONST

运算符的优先级

下表按照运算符的优先级从高到低列出了所有的运算符。

方法 运算符 描述
:: 常量解析运算符
[ ] [ ]= 元素引用、元素集合
** 指数
! ~ + - 非、补、一元加、一元减(最后两个的方法名为 [email protected][email protected]
    / %
乘法、除法、求模
    -
加法和减法
>> << 位右移、位左移
& 位与
^ | 位异或、位或
<= < > >= 比较运算符
<=> == === != =~ !~ 相等和模式匹配运算符(!= 和 !~ 不能被定义为方法)
&& 逻辑与
|| 逻辑或
.. … 范围(包含、不包含)
? : 三元 if-then-else
= %= { /= -= += = &= >>= <<= *= &&=
defined? 检查指定符号是否已定义
not 逻辑否定
or and 逻辑组成

数据类型

Ruby支持的数据类型包括基本的Number、String、Ranges、Symbols,以及true、false和nil这几个特殊值,同时还有两种重要的数据结构——Array和Hash。

数值(Number)

整型(Integer)
整型分两种,如果在31位以内(四字节),那为Fixnum实例。如果超过,即为Bignum实例。
整数范围从 -230 到 230-1 或 -262 到 262-1。在这个范围内的整数是类 Fixnum 的对象,在这个范围外的整数存储在类 Bignum 的对象中。
您可以在整数前使用一个可选的前导符号,一个可选的基础指标(0 对应 octal,0x 对应 hex,0b 对应 binary),后跟一串数字。下划线字符在数字字符串中被忽略。
您可以获取一个 ASCII 字符或一个用问号标记的转义序列的整数值。

  1. 123 # Fixnum 十进制
  2. 1_234 # Fixnum 带有下划线的十进制
  3. -500 # 负的 Fixnum
  4. 0377 # 八进制
  5. 0xff # 十六进制
  6. 0b1011 # 二进制
  7. "a".ord # "a" 的字符编码
  8. ?\n # 换行符(0x0a)的编码
  9. 12345678901234567890 # Bignum

浮点型
Ruby 支持浮点数。它们是带有小数的数字。浮点数是类 Float 的对象,且可以是下列中任意一个。

  1. 123.4 # 浮点值
  2. 1.0e6 # 科学记数法
  3. 4E20 # 不是必需的
  4. 4e+20 # 指数前的符号

字符串(String)

Ruby 中的 String 对象用于存储或操作一个或多个字节的序列。
Ruby 字符串分为单引号字符串(’)和双引号字符串(”),区别在于双引号字符串能够支持更多的转义字符。

  1. #!/usr/bin/ruby -w
  2. puts ‘escape using "\\"‘;
  3. puts ‘That\‘s right‘;
  4. escape using "\"
  5. That‘s right

可以使用序列 #{ expr } 替换任意 Ruby 表达式的值为一个字符串。在这里,expr 可以是任意的 Ruby 表达式。

  1. puts "Multiplication Value : #{24*60*60}";
  2. Multiplication Value : 86400
  3. name="Ruby"
  4. puts name
  5. puts "#{name+",ok"}"
  6. Ruby
  7. Ruby,ok

转义字符

反斜杠符号 十六进制字符 描述
\a 0x07 报警符
\b 0x08 退格键
\cx Control-x
\C-x Control-x
\e 0x1b 转义符
\f 0x0c 换页符
\M-\C-x Meta-Control-x
\n 0x0a 换行符
\nnn 八进制表示法,其中 n 的范围为 0.7
\r 0x0d 回车符
\s 0x20 空格符
\t 0x09 制表符
\v 0x0b 垂直制表符
\x 字符 x
\xnn 十六进制表示法,其中 n 的范围为 0.9、 a.f 或 A.F

字符编码
Ruby 的默认字符集是 ASCII,字符可用单个字节表示。如果您使用 UTF-8 或其他现代的字符集,字符可能是用一个到四个字节表示。
您可以在程序开头使用 $KCODE 改变字符集

$KCODE = ‘u’

a ASCII (与 none 相同)。这是默认的。
e EUC。
n None (与 ASCII 相同)。
u UTF-8。

数组(Array)

Ruby 数组是任何对象的有序整数索引集合。数组中的每个元素都与一个索引相关,并可通过索引进行获取。
数组的索引从 0 开始,这与 C 或 Java 中一样。一个负数的索相对于数组的末尾计数的,也就是说,索引为 -1 表示数组的最后一个元素,-2 表示数组中的倒数第二个元素,依此类推。
Ruby 数组可存储诸如 String、 Integer、 Fixnum、 Hash、 Symbol 等对象,甚至可以是其他 Array 对象。
Ruby 数组不需要指定大小,当向数组添加元素时,Ruby 数组会自动增长。

  1. names = Array.new
  2. names = Array.new(20) #创建数组的同时设置数组的大小
  3. puts names.size # 返回 20
  4. puts names.length # 返回 20
  5. names = Array.new(4, "mac")
  6. puts "#{names}"
  7. #["mac", "mac", "mac", "mac"]
  8. nums = Array.new(10) { |e| e = e * 2 }
  9. puts "#{nums}"
  10. #[0, 2, 4, 6, 8, 10, 12, 14, 16, 18]
  11. nums = Array[1, 2, 3, 4,5]
  12. nums = Array.[](1, 2, 3, 4,5)
  13. digits = Array(0..9)
  14. puts "#{digits}"
  15. #[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

哈希(Hash)

哈希(Hash)是类似 “key” => “value” 这样的键值对集合。哈希类似于一个数组,只不过它的索引不局限于使用数字。
Hash 的索引(或者叫”键”)几乎可以是任何对象。
Hash 虽然和数组类似,但却有一个很重要的区别:Hash 的元素没有特定的顺序。 如果顺序很重要的话就要使用数组了。

  1. months = Hash.new
  2. # 创建带有默认值的哈希
  3. months = Hash.new( "month" )
  4. months = Hash.new "month"
  5. #当您访问带有默认值的哈希中的任意键时,如果键或值不存在,访问哈希将返回默认值
  6. puts "#{months[0]}"
  7. puts "#{months[72]}"
  8. #month
  9. #month
  10. H = Hash["a" => 100, "b" => 200]
  11. puts "#{H[‘a‘]}"
  12. puts "#{H[‘b‘]}"
  13. #100
  14. #200

范围(Range)

Ruby 支持范围,并允许我们以不同的方式使用范围:

  • 作为序列的范围
  • 作为条件的范围
  • 作为间隔的范围
  1. (1..5) #==> 1, 2, 3, 4, 5
  2. (1...5) #==> 1, 2, 3, 4
  3. (‘a‘..‘d‘) #==> ‘a‘, ‘b‘, ‘c‘, ‘d‘
  4. #可以使用 to_a 方法把范围转换为列表。
  5. range1 = (1..10).to_a #[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
  6. #可以通过多种方式检查它们的内容
  7. digits = 0..9
  8. puts digits.include?(5)
  9. ret = digits.min
  10. puts "最小值为 #{ret}"
  11. ret = digits.max
  12. puts "最大值为 #{ret}"
  13. ret = digits.reject {|i| i < 5 }
  14. puts "不符合条件的有 #{ret}"
  15. digits.each do |digit|
  16. puts "在循环中 #{digit}"
  17. end
  18. #其中每个集合的第一行包含单词 start,最后一行包含单词 end.
  19. while gets
  20. print if /start/../end/
  21. end
  22. score = 70
  23. result = case score
  24. when 0..40
  25. "糟糕的分数"
  26. when 41..60
  27. "快要及格"
  28. when 61..70
  29. "及格分数"
  30. when 71..100
  31. "良好分数"
  32. else
  33. "错误的分数"
  34. end
  35. puts result
  36. #检查指定值是否在指定的范围内。需要使用 === 相等运算符来完成计算
  37. if ((1..10) === 5)
  38. puts "5 在 (1..10)"
  39. end
  40. if ((‘a‘..‘j‘) === ‘c‘)
  41. puts "c 在 (‘a‘..‘j‘)"
  42. end
  43. if ((‘a‘..‘j‘) === ‘z‘)
  44. puts "z 在 (‘a‘..‘j‘)"
  45. end

迭代器(iterator)

迭代器是集合支持的方法。存储一组数据成员的对象称为集合。在 Ruby 中,数组(Array)和哈希(Hash)可以称之为集合。
迭代器返回集合的所有元素,一个接着一个。

each 迭代器

  1. #each 迭代器总是与一个块关联。它向块返回数组的每个值,一个接着一个。值被存储在变量 i 中
  2. ary = [1,2,3,4,5]
  3. ary.each do |i|
  4. puts i
  5. end
  6. #当您想要对每个值进行一些操作以便获得新的数组时,您通常使用 collect 方法。例如,下面的代码会生成一个数组,其值是 a 中每个值的 10 倍。
  7. a = [1,2,3,4,5]
  8. b = a.collect{|x| 10*x}
  9. puts b

collect 迭代器

collect 迭代器返回集合的所有元素。

  1. a = [1,2,3,4,5]
  2. b = Array.new
  3. b = a.collect{ |x|x }
  4. puts b

条件判断与循环

  1. #!/usr/bin/ruby
  2. # -*- coding: UTF-8 -*-
  3. #if 表达式用于条件执行。值 false 和 nil 为假,其他值都为真。请注意,Ruby 使用 elsif,不是使用 else if 和 elif。
  4. #如果 conditional 为真,则执行 code。如果 conditional 不为真,则执行 else 子句中指定的 code。
  5. #通常我们省略保留字 then 。若想在一行内写出完整的 if 式,则必须以 then 隔开条件式和程式区块。
  6. x=1
  7. if x > 2
  8. puts "x 大于 2"
  9. elsif x <= 2 and x!=0
  10. puts "x 是 1"
  11. else
  12. puts "无法得知 x 的值"
  13. end
  14. #if修饰词组表示当 if 右边之条件成立时才执行 if 左边的式子。即如果 conditional 为真,则执行 code。
  15. $debug=1
  16. print "debug\n" if $debug
  17. #unless式和 if式作用相反,即如果 conditional 为假,则执行 code。如果 conditional 为真,则执行 else 子句中指定的 code。
  18. $var = 1
  19. print "1 -- 这一行输出\n" if $var
  20. print "2 -- 这一行不输出\n" unless $var
  21. $var = false
  22. print "3 -- 这一行输出\n" unless $var
  23. #unless式和 if式作用相反,即如果 conditional 为假,则执行 code。如果 conditional 为真,则执行 else 子句中指定的 code。
  24. 以上是关于Ruby初探的主要内容,如果未能解决你的问题,请参考以下文章

    Ruby初探

    初探JSP与LEeclipse

    ruby Ruby片段

    ruby 方便的片段

    ruby serverspec片段

    ruby 片段