Ruby
1.1 Ruby 的运行方法
1.1.1 hello.rb
cd c:
ruby helloruby.rb
1.1.2 irb 命令的执行方法
> irb
irb(main):001:0>print("Hello, Ruby.\n")
Hello, Ruby.
=> nil
字符串、数值、时间等各种数据,在 Ruby 中都是对象。
1.2 字符串
1.2.1 \n与\
- \n 换行符
- \ 转义符
// 输出 Hello, "Ruby".
print("Hello, \"Ruby\".\n")
// 输出 Hello \ Ruby!
print("Hello \\ Ruby!")
1.2.2 ’ ’ 与 " "
// 输出 Hello, \nRuby\n!\n
print('Hello, \nRuby\n!\n')
1.3 方法的调用
Ruby 在调用方法时可以省略 ()。
1.4 puts与print的区别
puts 方法与 print 方法稍有区别,puts 方法在输出结果的末尾一定会输出换行符。
1.5 p 方法
puts "100" #=> 100
puts 100 #=> 100
p "100" #=> "100"
p 100 #=> 100
// 输出 Hello, Ruby.
print("Hello, Ruby.\n")
// Hello,
// Ruby.
puts "Hello, \nRuby."
// "Hello, \n\tRuby."
p "Hello, \n\tRuby."
1.6 编码问题
> ruby kiritsubo.rb
kiritsubo.rb:1: invalid multibyte char (US-ASCII)
kiritsubo.rb:1: invalid multibyte char (US-ASCII)
解决方案
Ruby 程序的编码方式,是通过在程序的首行代码添加注释“# encoding: 编码方式”
例如:
# encoding: UTF-8
print("你好呀, Ruby.\n")
1.7 数值
Fixnum 整数对象
Float 浮点数对象
1.8 变量
x = 10
y = 20
z = 30
area = (x*y + y*z + z*x) * 2
volume = x * y * z
print "表面积=", area, "\n"
print "体积=", volume, "\n"
输出: 表面积=2200
体积=6000
puts "表面积 = #{area}"
1.9 注释
单行注释以 # 字符开始
多行注释使用 =begin 和 =end 语法
=begin
这是一个多行注释。
可扩展至任意数量的行。
但 =begin 和 =end 只能出现在第一行和最后一行。
=end
1.10 控制语句
- 顺序控制:按照程序的编写顺序,从头到尾执行。
- 条件控制:若某条件成立,则执行○○,否则执行 ××。
- 循环控制:在某条件成立之前,反复执行○○。
- 异常控制:发生某种异常时,执行○○。
1.11 条件判断:if~then~end
if 条件 then
条件成立时执行的处理
else
条件不成立时执行的处理
end
a = 20
if a >= 10 then
print "bigger\n"
end
// then 可以省略
if a <= 9
print "smaller\n"
end
1.12 循环
1.12.1 while 语句
while 循环条件 do
希望循环的处理
end
i = 1
while i <= 10
print i, "\n"
i = i + 1
end
1.12.2 times 方法
循环处理的循环次数如果已确定,使用 times 方法会更加简单。
循环次数 .times do
希望循环的处理
end
100.times do
print "All work and no play makes Jack a dull boy.\n"
end
def 定义函数
# 对象
class Greeter
def initialize(name = "word")
@name = name
end
def say_hi
puts "Hi #{@name}!"
end
def say_bye
puts "Bye #{@name}, come back soon."
end
end
g = Greeter.new("Pat")
g.say_hi
g.say_bye
Greeter.instance_methods
g.respond_to?("name") => false
# g是否支持 say_hi 函数
g.respond_to?("say_hi") => true
Greeter对象包含的所有
的函数
Greeter.instance_methods
Greeter对象自定义函数
Greeter.instance_methods(false)
循环,迭代
如果 @names 对象可以回应 each 函数,那它就是可以被迭代的
迭代结构
@names.each do |name|
puts "Hello #{name}!"
end
@names 是否支持 join 函数
@names.respond_to?("join")
if FILE == $0 程序入口
__FILE__
是一个 魔法值
2.1 数组
// 空数组
names = []
names = ["小林", "林", "高野", "森冈"]
// 小林
names[0]
// 林
names[1]
names[5] = "刘露"
// ["小林", "林", "高野", "森冈", nil, "刘露"]
names
// 返回数组长度
names.size
// 遍历数组
names.each do |item|
pust item
end
不同点
- 在保存对象时,如果指定了数组中不存在的索引值时,则数组的大小会随之而改变,用nil占位
即动态数组
names.size
返回数组长度- 遍历数组
数组 .each do | 变量 | 希望循环的处理 end
2.2 散列
散列是键值对的一种数据结构,在 Ruby 中,一般是以字符串或者符号(Symbol)作为键,来保存对应的对象
eg:address = {:name => "高桥", :pinyin => "gaoqiao", :postal => "1234567"}
符号
符号也是对象,一般作为名称标签来使用,用来表示方法等的对象的名称.可以将符号简单理解为为轻量级的字符串
sym = :foo
sym2 = :"foo"
符号与字符串之间的转换
符号转字符串
to_s()
字符串转符号
to_sym()
>> irb
>> sym = "foo"
=> "foo"
>> sym.to_sym()
=> :foo
>> :foo.to_s()
=> "foo"
散列使用
>> address = {
name: "高桥", pinyin: "gaoqiao"}
=> {
:name=>"高桥", :pinyin=>"gaoqiao"}
>> address[:name]
=> "高桥"
>> address[:name] = "刘露"
=> "刘露"
>> address
=> {
:name=>"刘露", :pinyin=>"gaoqiao"}
>> address[:tel] = "17809212776"
=> 17809212776
>> address
=> {
:name=>"刘露", :pinyin=>"gaoqiao", :tel=>17809212776}
错误使用 address[name]
>> address = {
name: "高桥", pinyin: "gaoqiao"}
=> {
:name=>"高桥", :pinyin=>"gaoqiao"}
>> address[name]
=> NameError (undefined local variable or method `name' for main:Object)
散列的循环
语法
散列 .each do | 键变量 , 值变量 |
希望循环的处理
end
例子
>> address = {
name: "高桥", pinyin: "gaoqiao"}
=> {
:name=>"高桥", :pinyin=>"gaoqiao"}
>> address.each do |key, value|
?> puts "#{key}: #{value}"
>> end
name: 高桥
pinyin: gaoqiao
=> {
:name=>"高桥", :pinyin=>"gaoqiao"}
2.3 正则表达式
语法
/Ruby/
匹配字符串
/ 模式 / =~ 希望匹配的字符串
若匹配成功则返回匹配部分的位置(从0开始计数),反之则返回 nil
例子
>> /Ruby/ =~ "Yet Another Ruby Hacker,"
=> 12
>> /Yet Another Ruby Hacker,/ =~ "Ruby"
=> nil
正则表达式右边的 / 后面加上 i 表示不区分大小写匹配
>> /Ruby/ =~ "ruby"
=> nil
>> /Ruby/ =~ "RUBY"
=> nil
>> /Ruby/i =~ "ruby"
=> 0
>> /Ruby/i =~ "RUBY"
=> 0
>> /Ruby/i =~ "rUbY"
=> 0
nil 是什么
nil 是一个特殊的值,表示对象不存在
3.创建命令
本章介绍 Ruby 从命令行读取并处理数据的方法
3.1 命令行的输入数据
ARGV
Ruby 程序中,使用 ARGV
这个 Ruby 预定义好的数组来获取从命令行传递过来的数据。数组 ARGV 中的元
素,就是在命令行中指定的脚本字符串参数。
代码清单 print_argv.rb
puts "首个参数: #{ARGV[0]}"
puts "第2 个参数: #{ARGV[1]}"
puts "第3 个参数: #{ARGV[2]}"
执行示例
> ruby print_argv.rb 1st 2nd 3rd
首个参数: 1st
第 2 个参数: 2nd
第 3 个参数: 3rd
代码清单 happy_birth.rb
name = ARGV[0]
print "Happy Birthday, ", name, "!\n"
执行示例
> ruby happy_birth.rb Ruby
Happy Birthday, Ruby!
to_i()
把字符串转换为整数
代码清单 arg_arith.rb
num0 = ARGV[0].to_i
num1 = ARGV[1].to_i
puts "#{num0} + #{num1} = #{num0 + num1}"
puts "#{num0} - #{num1} = #{num0 - num1}"
puts "#{num0} * #{num1} = #{num0 * num1}"
puts "#{num0} / #{num1} = #{num0 / num1}"
执行示例
> ruby arg_arith.rb 5 3
5 + 3 = 8
5 - 3 = 2
5 * 3 = 15
5 / 3 = 1
3.2 文件的读取
Ruby 脚本除了读取命令行传递过来的字符串参数外,还可以读取预先写在文件里的数据
Ruby 的源代码中,有一个名为 ChangeLog 的文本文件。文件里面记录了 Ruby 相关的修改日志
读取文件内容的流程 ?
① 打开文件
② 读取文件的文本数据
③ 输出文件的文本数据
④ 关闭文件
从文件中读取指定模式的内容并输出 ?
方法的定义
语法
def 方法名
希望执行的处理
end
例子
def h(name)
puts "Hello #{name}!"
end
h('liulu')
其他文件的引用
require
require 希望使用的库名
4.对象、变量和常量
4.1 对象
- 数值对象
- 数值对象
- 数组对象、散列对象
- 正则表达式对象
- 时间对象
- 文件对象
- 符号对象
除此以外,Ruby 还有范围对象(Range)、异常对象(Exception)等
4.2 类
Ruby 的类(class)表示的就是对象的种类
对象拥有什么特性等,这些都是由类来决定的。到目前为止,我们介绍过的对象与其所属类的对应关系
- Numeric(数值)
- String(数值)
- Array(数组)
- Hash(散列)
- Regexp(正则)
- File(文件)
- Symbol(符号)
eg: 字符串对象 "foo" 是 String 类的实例
4.3 变量
- 局部变量(local variable)以英文字母或者 _ 开头
- 全局变量(global variable)以 $ 开头
- 实例变量(instance variable)以 @ 开头
- 类变量(class variable)以 @@ 开头,且必须初始化后才能在方法定义中使用
特殊变量
- 伪变量(pseudo variable)预先定义好的代表某特定值的特殊变量,nil、true、false、self
- 预定义变量(Pre-defined Variable)
4.4 常量
常量以大写英文字母开头
注意
- 常量不能定义在方法内
- 引用一个未初始化的常量会产生错误
- 对已经初始化的常量赋值会产生警告
4.5 保留字
在程序中作为名称使用时会受到限制。这些受到限制的单词,我们称为保留字
4.6 多重赋值
a, b, c = 1, 2, 3
合并执行多个赋值操作
即使= 左右两边列表的数量不相等,不会报错,Ruby 会自动将 nil 赋值给未分配值的变量
>> a, b, c, d = 1, 2
>> p [a, b, c]
=> [1, 2, nil]
变量前加上*
,表示 Ruby 会将未分配的值封装为数组赋值给该变量
>> a, b, *c = 1, 2, 3, 4, 5
>> p [a, b, c]
=> [1, 2, [3, 4, 5]]
>> a, *b, c = 1, 2, 3, 4, 5
>> p [a, b, c]
=> [1, [2, 3, 4], 5]