|第 1 章|
|第 2 章|
|第 3 章|
|第 4 章|
|第 5 章|
|第 6 章|
|第 7 章|
|第 8 章|
|第 9 章|
|第 10 章|
|第 11 章|
|第 12 章|
|第 13 章|
|第 14 章|
|第 15 章|
|第 16 章|
|第 17 章|
|第 18 章|
|第 19 章|
|第 20 章|
|第 21 章|
|第 22 章|
|第 23 章|
第 1 章
代码清单 1.1:helloruby.rb
1
| print("Hello, Ruby.\n")
|
代码清单 1.2:put_and_p.rb
1
2
| puts "Hello,\n\tRuby."
p "Hello,\n\tRuby."
|
代码清单 1.3:kiritsubo.rb
1
2
| print "话说从前某一朝天皇时代,后宫妃嫔甚多,\n"
print "其中有一更衣,出身并不十分高贵,却蒙皇上特别宠爱\n"
|
代码清单 1.4:area_volume.rb
1
2
3
4
5
6
7
| x = 10
y = 20
z = 30
area = (x*y + y*z + z*x) * 2
volume = x * y * z
print "表面积=", area, "\n"
print "体积=", volume, "\n"
|
代码清单 1.5:comment_sample.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
| =begin
《Ruby基础教程》第5版例子
注释的使用例子
2006/06/16 创建
2006/07/01 追加一部分注释
2013/04/01 第4版更新
2015/10/01 第5版更新
=end
x = 10 # 宽
y = 20 # 长
z = 30 # 高
# 计算表面积和体积
area = (x*y + y*z + z*x) * 2
volume = x * y * z
# 输出
print "表面积=", area, "\n"
print "体积=", volume, "\n"
|
代码清单 1.6:greater_smaller.rb
1
2
3
4
5
6
7
| a = 20
if a >= 10 then
print "greater\n"
end
if a <= 9 then
print "smaller\n"
end
|
代码清单 1.7:greater_smaller_else.rb
1
2
3
4
5
6
| a = 20
if a >= 10
print "greater\n"
else
print "smaller\n"
end
|
第 2 章
代码清单 2.1:print_lin.rb
1
2
3
4
5
6
7
| names = ["小林", "林", "高野", "森冈"]
["小林", "林", "高野", "森冈"]
names.each do |name|
if /林/ =~ name
puts name
end
end
|
第 3 章
代码清单 3.1:print_argv.rb
1
2
3
4
5
| puts "首个参数: #{ARGV[0]}"
puts "第2个参数: #{ARGV[1]}"
puts "第3个参数: #{ARGV[2]}"
puts "第4个参数: #{ARGV[3]}"
puts "第5个参数: #{ARGV[4]}"
|
代码清单 3.2:happy_birth.rb
1
2
| name = ARGV[0]
print "Happy Birthday, ", name, "!\n"
|
代码清单 3.3:arg_arith.rb
1
2
3
4
5
6
| 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}"
|
代码清单 3.4:read_text.rb
1
2
3
4
5
| filename = ARGV[0]
file = File.open(filename) # ① 打开文件
text = file.read # ② 读取文本
print text # ③ 输出文本
file.close # ④ 关闭文件
|
代码清单 3.5:read_text_simple.rb
1
2
3
| filename = ARGV[0]
text = File.read(filename)
print text
|
代码清单 3.6:read_text_oneline.rb
1
| print File.read(ARGV[0])
|
代码清单 3.7:read_line.rb
1
2
3
4
5
6
| filename = ARGV[0]
file = File.open(filename)
file.each_line do |line|
print line
end
file.close
|
代码清单 3.8:simple_grep.rb
1
2
3
4
5
6
7
8
9
10
| pattern = Regexp.new(ARGV[0])
filename = ARGV[1]
file = File.open(filename)
file.each_line do |line|
if pattern =~ line
print line
end
end
file.close
|
代码清单 3.9:hello_ruby2.rb
1
2
3
4
5
| def hello
puts "Hello, Ruby"
end
hello()
|
代码清单 3.10:grep.rb
1
2
3
4
5
6
7
8
9
| def simple_grep(pattern, filename)
file = File.open(filename)
file.each_line do |line|
if pattern =~ line
print line
end
end
file.close
end
|
代码清单 3.11:use_grep.rb
1
2
3
4
5
| require_relative "grep" # 读取grep.rb(省略“.rb”)
pattern = Regexp.new(ARGV[0])
filename = ARGV[1]
simple_grep(pattern, filename) # 调用simple_grep方法
|
代码清单 专栏:p_and_pp.rb
1
2
3
4
5
6
7
8
9
| require "pp"
books = [
{ title: "猫街", author: "萩原朔太郎" },
{ title: "猫的事务所", author: "宫泽贤治" },
{ title: "猫语教科书", author: "Paul Gallico" },
]
p books
pp books
|
第 4 章
代码清单 4.1:scopetest.rb
1
2
3
4
5
6
7
| $x = 0
x = 0
require_relative "sub"
p $x #=> 1
p x #=> 0
|
代码清单 4.2:sub.rb
1
2
| $x = 1 ## 对全局变量赋值
x = 1 ## 对局部变量赋值
|
第 5 章
代码清单 5.1:ad2pingcheng.rb
1
2
3
4
5
| #将西历转换为平成纪年
ad = ARGV[0].to_i
pingcheng = ad - 1988
puts pingcheng
|
代码清单 5.2:if_elsif.rb
1
2
3
4
5
6
7
8
9
| a = 10
b = 20
if a > b
puts "a比b大"
elsif a < b
puts "a比b小"
else
puts "a与b相等"
end
|
代码清单 5.3:unless.rb
1
2
3
4
5
| a = 10
b = 20
unless a > b
puts "a不比b大"
end
|
代码清单 5.4:case.rb
1
2
3
4
5
6
7
8
9
10
11
| tags = [ "A", "IMG", "PRE" ]
tags.each do |tagname|
case tagname
when "P","A","I","B","BLOCKQUOTE"
puts "#{tagname} has child."
when "IMG", "BR"
puts "#{tagname} has no child."
else
puts "#{tagname} cannot be used."
end
end
|
代码清单 5.5:case_class.rb
1
2
3
4
5
6
7
8
9
10
11
| array = [ "a", 1, nil ]
array.each do |item|
case item
when String
puts "item is a String."
when Numeric
puts "item is a Numeric."
else
puts "item is something."
end
end
|
第 6 章
代码清单 6.1:times.rb
1
2
3
| 7.times do
puts "满地油菜花"
end
|
代码清单 6.2:times2.rb
1
2
3
| 5.times do |i|
puts "第#{i}次的循环。"
end
|
代码清单 6.3:times3.rb
1
2
3
| 5.times do |i|
puts "第#{i+1}次的循环。"
end
|
代码清单 6.4:for.rb
1
2
3
4
5
| sum = 0
for i in 1..5
sum = sum + i
end
puts sum
|
代码清单 6.5:for_names.rb
1
2
3
4
| names = ["awk", "Perl", "Python", "Ruby"]
for name in names
puts name
end
|
代码清单 6.6:while.rb
1
2
3
4
5
| i = 1
while i < 3
puts i
i += 1
end
|
代码清单 6.7:while2.rb
1
2
3
4
5
6
7
| sum = 0
i = 1
while i <= 5
sum += i
i += 1
end
puts sum
|
代码清单 6.8:while3.rb
1
2
3
4
5
6
7
| sum = 0
i = 1
while sum < 50
sum += i
i += 1
end
puts sum
|
代码清单 6.9:until.rb
1
2
3
4
5
6
7
| sum = 0
i = 1
until sum >= 50
sum += i
i+= 1
end
puts sum
|
代码清单 6.10:while_not.rb
1
2
3
4
5
6
7
| sum = 0
i = 1
while !(sum >= 50)
sum += i
i += 1
end
puts sum
|
代码清单 6.11:each_names.rb
1
2
3
4
| names = ["awk","Perl","Python","Ruby"]
names.each do |name|
puts name
end
|
代码清单 6.12:each.rb
1
2
3
4
5
| sum = 0
(1..5).each do |i|
sum= sum + i
end
puts sum
|
代码清单 6.13:break_next.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
| puts "break的例子:"
i = 0
["Perl", "Python", "Ruby", "Scheme"].each do |lang|
i += 1
if i == 3
break
end
p [i,lang]
end
puts "next的例子:"
i = 0
["Perl", "Python", "Ruby", "Scheme"].each do |lang|
i += 1
if i == 3
next
end
p [i,lang]
end
|
代码清单 6.14:ten_lines_grep.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
| pattern = Regexp.new(ARGV[0])
filename = ARGV[1]
max_matches = 10 # 输出的最大行数
matches = 0 # 已匹配的行数
file = File.open(filename)
file.each_line do |line|
if matches >= max_matches
break
end
if pattern =~ line
matches += 1
puts line
end
end
file.close
|
代码清单 6.15:strip.rb
1
2
3
4
5
6
7
| file = File.open(ARGV[0])
file.each_line do |line|
next if /^\s*$/ =~ line # 空行
next if /^#/ =~ line # 以“#”开头的行
puts line
end
file.close
|
代码清单 6.16:hello.rb
1
2
3
4
5
6
7
8
| # Hello, World
puts("hello, world")
# 日语
puts("こんにちは世界")
# 汉语
puts("你好,世界")
|
代码清单 6.17:stripped_hello.rb
1
2
3
| puts("hello, world")
puts("こんにちは世界")
puts("你好,世界")
|
第 7 章
代码清单 7.1:times_with_param.rb
1
2
3
| 5.times do |i|
puts "第#{i}次循环。"
end
|
代码清单 7.2:hello_with_name.rb
1
2
3
4
5
| def hello(name)
puts "Hello, #{name}."
end
hello("Ruby")
|
代码清单 7.3:hello_with_default.rb
1
2
3
4
5
6
| def hello(name="Ruby")
puts "Hello, #{name}."
end
hello() # 省略参数的调用
hello("Newbie") # 指定参数的调用
|
代码清单 7.4:myloop.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
| def myloop
while true
yield # 执行块
end
end
num = 1 # 初始化num
myloop do
puts "num is #{num}" # 输出num
break if num > 10 # num超过10时跳出循环
num *= 2 # num乘2
end
|
第 8 章
代码清单 8.1:hello_class.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
| class HelloWorld # class语句
def initialize(myname = "Ruby") # initialize方法
@name = myname # 初始化实例变量
end
def hello # 实例方法
puts "Hello, world. I am #{@name}."
end
end
bob = HelloWorld.new("Bob")
alice = HelloWorld.new("Alice")
ruby = HelloWorld.new
bob.hello
|
代码清单 8.2:hello_class2(部分).rb
1
2
3
4
5
6
7
8
9
10
11
| class HelloWorld
...
def name # 获取@name
@name
end
def name=(value) # 修改@name
@name = value
end
...
end
|
代码清单 8.3:hello_class3(部分).rb
1
2
3
4
5
6
7
8
| class HelloWorld
attr_accessor :name
...
def greet
puts "Hi, I am #{self.name}."
end
end
...
|
代码清单 8.4:hello_count.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
| class HelloCount
@@count = 0 # 调用hello方法的次数
def HelloCount.count # 读取调用次数的类方法
@@count
end
def initialize(myname="Ruby")
@name = myname
end
def hello
@@count += 1 # 累加调用次数
puts "Hello, world. I am #{@name}.\n"
end
end
bob = HelloCount.new("Bob")
alice = HelloCount.new("Alice")
ruby = HelloCount.new
p HelloCount.count #=> 0
bob.hello
alice.hello
ruby.hello
p HelloCount.count #=> 3
|
代码清单 8.5:acc_test.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
| class AccTest
def pub
puts "pub is a public method."
end
public :pub # 把pub方法设定为public(可省略)
def priv
puts "priv is a private method."
end
private :priv # 把priv方法设定为private
end
acc = AccTest.new
acc.pub
acc.priv
|
代码清单 8.6:point.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
| class Point
attr_accessor :x, :y # 定义存取器
protected :x=, :y= # 把x=与y=设定为protected
def initialize(x=0.0, y=0.0)
@x, @y = x, y
end
def swap(other) # 置换x、y值的方法
tmp_x, tmp_y = @x, @y
@x, @y = other.x, other.y
other.x, other.y = tmp_x, tmp_y # 在同一个类中
# 可以被调用
return self
end
end
p0 = Point.new
p1 = Point.new(1.0, 2.0)
p [ p0.x, p0.y ] #=> [0.0, 0.0]
p [ p1.x, p1.y ] #=> [1.0, 2.0]
p0.swap(p1)
p [ p0.x, p0.y ] #=> [1.0, 2.0]
p [ p1.x, p1.y ] #=> [0.0, 0.0]
p0.x = 10.0 #=> 错误(NoMethodError)
|
代码清单 8.7:ext_string.rb
1
2
3
4
5
6
7
8
9
10
| class String
def count_word
ary = self.split(/\s+/) # 用空格分割self
# 分解成数组
return ary.size # 返回分割后的数组的元素总数
end
end
str = "Just Another Ruby Newbie"
p str.count_word #=> 4
|
代码清单 8.8:ring_array.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
| class RingArray < Array # 指定父类
def [](i) # 重定义运算符[]
idx = i % size # 计算新索引值
super(idx) # 调用父类中同名的方法
end
end
wday = RingArray["日", "月", "火", "水", "木", "金", "土"]
wday = RingArray["日", "月", "火", "水", "木", "金", "土"]
p wday[6] #=> "土"
p wday[11] #=> "木"
p wday[15] #=> "月"
p wday[-1] #=> "土"
|
代码清单 8.9:alias_sample.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
| class C1 # 定义C1
def hello # 定义hello
"Hello"
end
end
class C2 < C1 # 定义继承了C1 的子类C2
alias old_hello hello # 设定别名old_hello
def hello # 重定义hello
"#{old_hello}, again"
end
end
obj = C2.new
p obj.old_hello #=> "Hello"
p obj.hello #=> "Hello, again
|
代码清单 8.10:mixin_sample.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
| module MyModule
# 希望提供的共通方法等
end
class MyClass1
include MyModule
# MyClass1中特有的方法等
end
class MyClass2
include MyModule
# MyClass2中特有的方法等
end
|
代码清单 8.11:hello_module.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
| module HelloModule # module关键字
Version = "1.0" # 定义常量
def hello(name) # 定义方法
puts "Hello, #{name}."
end
module_function :hello # 指定hello方法为模块函数
end
p HelloModule::Version #=> "1.0"
HelloModule.hello("Alice") #=> Hello, Alice.
include HelloModule # 包含模块
p Version #=> "1.0"
hello("Alice") #=> Hello, Alice.
|
代码清单 8.12:mixin_test.rb
1
2
3
4
5
6
7
8
9
10
11
12
| module M
def meth
"meth"
end
end
class C
include M # 包含M模块
end
c = C.new
p c.meth #=> meth
|
代码清单 8.13:fetch_and_downcase.rb
1
2
3
4
5
6
7
8
| def fetch_and_downcase(ary, index)
if str = ary[index]
return str.downcase
end
end
ary = ["Boo", "Foo", "Woo"]
p fetch_and_downcase(ary, 1) #=> "foo"
|
代码清单 8.14:http_get.rb
1
2
3
4
5
6
| require "net/http"
require "uri"
url = URI.parse("http://www.ruby-lang.org/ja/")
http = Net::HTTP.start(url.host, url.port)
doc = http.get(url.path)
puts puts doc.body
|
第 9 章
代码清单 9.1:point.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
| class Point
attr_reader :x, :y
def initialize(x=0, y=0)
@x, @y = x, y
end
def inspect # 用于显示
"(#{x}, #{y})"
end
def +(other) # x、y分别进行加法运算
self.class.new(x + other.x, y + other.y)
end
def -(other) # x、y分别进行减法运算
self.class.new(x - other.x, y - other.y)
end
end
point0 = Point.new(3, 6)
point1 = Point.new(1, 8)
p point0 #=> (3, 6)
p point1 #=> (1, 8)
p point0 + point1 #=> (4, 14)
p point0 - point1 #=> (2, -2)
|
代码清单 9.2:point1(部分).rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
| class Point
...
def +@
dup # 返回自己的拷贝
end
def -@
self.class.new(-x, -y) # 颠倒x、y各自的正负
end
def ~@
self.class.new(-y, x) # 使坐标翻转90度
end
end
point = Point.new(3, 6)
p +point #=> (3, 6)
p -point #=> (-3, -6)
p ~point #=> (-6, 3)
|
代码清单 9.3:point2(部分).rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
| class Point
...
def [](index)
case index
when 0
x
when 1
y
else
raise ArgumentError, "out of range `#{index}'"
end
end
def []=(index, val)
case index
when 0
self.x = val
when 1
self.y = val
else
raise ArgumentError, "out of range `#{index}'"
end
end
end
point = Point.new(3, 6)
p point[0] #=> 3
p point[1] = 2 #=> 2
p point[1] #=> 2
p point[2] #=>错误(ArgumentError)
|
第 10 章
代码清单 10.1:wc.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
| ltotal=0 # 行数合计
wtotal=0 # 单词数合计
ctotal=0 # 字数合计
ARGV.each do |file|
begin
input = File.open(file) # 打开文件(A)
l=0 # file内的行数
w=0 # file内的单词数
c=0 # file内的字数
input.each_line do |line|
l += 1
c += line.size
line.sub!(/^\s+/, "") # 删除行首的空白符
ary = line.split(/\s+/) # 用空白符分解
w += ary.size
end
input.close # 关闭文件
printf("%8d %8d %8d %s\n", l, w, c, file) # 整理输出格式
ltotal += l
wtotal += w
ctotal += c
rescue => ex
print ex.message, "\n" # 输出异常信息(B)
end
end
printf("%8d %8d %8d %s\n", ltotal, wtotal, ctotal, "total")
|
代码清单 copy:cp.rb
1
2
3
4
5
6
7
8
9
10
11
| def copy(from, to)
src = File.open(from) # 打开原文件from(A)
begin
dst = File.open(to, "w") # 打开目标文件to(B)
data = src.read
dst.write(data)
dst.close
ensure
src.close # (C)
end
end
|
第 11 章
代码清单 11.1:hash_each.rb
1
2
3
4
5
6
| sum = 0
outcome = {"参加费"=>1000, "挂件费用"=>1000, "联欢会费用"=>4000}
outcome.each do |pair|
sum += pair[1] # 指定值
end
puts "合计:#{sum}"
|
代码清单 11.2:hash_each2.rb
1
2
3
4
5
6
| sum = 0
outcome = {"参加费"=>1000, "挂件费用"=>1000, "联欢会费用"=>4000}
outcome.each do |item, price|
sum += price
end
puts "合计:#{sum}"
|
代码清单 11.3:file_each.rb
1
2
3
4
5
| file = File.open("sample.txt")
file.each_line do |line|
print line
end
file.close
|
代码清单 11.4:file_open.rb
1
2
3
4
5
| File.open("sample.txt") do |file|
file.each_line do |line|
print line
end
end
|
代码清单 11.5:file_open_no_block.rb
1
2
3
4
5
6
7
8
| file = File.open("sample.txt")
begin
file.each_line do |line|
print line
end
ensure
file.close
end
|
代码清单 11.6:sort_comp_count.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
| # %w(...)是一个用于生成一个以各单词作为元素的数组的字面量
ary = %w(
Ruby is a open source programming language with a focus
on simplicity and productivity. It has an elegant syntax
that is natural to read and easy to write
)
call_num = 0 # 块的调用次数
sorted = ary.sort do |a, b|
call_num += 1 # 累加块的调用次数
a.length <=> b.length
end
puts "排序结果 #{sorted}"
puts "数组的元素数量 #{ary.length}"
puts "调用块的次数 #{call_num}"
|
代码清单 11.7:myloop.rb
1
2
3
4
5
6
7
8
9
10
11
12
| def myloop
while true
yield # 执行块
end
end
num = 1 # 初始化num
myloop do
puts "num is #{num}" # 输出num
break if num > 100 # num超过100后跳出循环
num *= 2 # num乘2
end
|
代码清单 11.8:total.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
| def total(from, to)
result = 0 # 合计值
from.upto(to) do |num| # 处理从from到to的值
if block_given? # 如果有块的话
result += yield(num) # 累加经过块处理的值
else # 如果没有块的话
result += num # 直接累加
end
end
return result # 返回方法的结果
end
p total(1, 10) # 从1到10的和 => 55
p total(1, 10){|num| num ** 2 } # 从1到10的2次冥的和 => 385
|
代码清单 11.9:block_args_test.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
| def block_args_test
yield() # 0个块变量
yield(1) # 1个块变量
yield(1, 2, 3) # 3个块变量
end
puts "通过|a|接收块变量"
block_args_test do |a|
p [a]
end
puts
puts "通过|a, b, c|接收块变量"
block_args_test do |a, b, c|
p [a, b, c]
end
puts
puts "通过|*a|接收块变量"
block_args_test do |*a|
p [a]
end
puts
|
代码清单 11.10:proc1.rb
1
2
3
4
5
6
| hello = Proc.new do |name|
puts "Hello, #{name}."
end
hello.call("World")
hello.call("Ruby")
|
代码清单 11.11:total2.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
| def total2(from, to, &block)
result = 0 # 合计值
from.upto(to) do |num| # 处理从from到to的值
if block # 如果有块的话
result += # 累加经过块处理的值
block.call(num)
else # 如果没有块的话
result += num # 直接累加
end
end
return result # 返回方法的结果
end
p total2(1, 10) # 从1到10的和 => 55
p total2(1, 10){|num| num ** 2 } # 从1到10的2次冥的和 => 385
|
代码清单 11.12:call_each.rb
1
2
3
4
5
6
7
| def call_each(ary, &block)
ary.each(&block)
end
call_each [1, 2, 3] do |item|
p item
end
|
代码清单 11.13:local_and_block.rb
1
2
3
4
5
6
7
8
9
| x = 1 # 初始化x
y = 1 # 初始化y
ary = [1, 2, 3]
ary.each do |x| # 将x作为块变量使用
y = x # 将x赋值给y
end
p [x, y] # 确认x与y的值
|
代码清单 11.14:local_and_block2.rb
1
2
3
4
5
6
7
8
9
| x = y = z = 0 # 初始化x、y、z
ary = [1, 2, 3]
ary.each do |x; y| # 使用块变量x,块局部变量y
y = x # 代入块局部变量y
z = x # 代入不是块局部变量的变量z
p [x, y, z] # 确认块内的x、y、z的值
end
puts
p [x, y, z] # 确认x、y、z的值
|
第 12 章
无代码清单。
第 13 章
代码清单 13.1:list.rb
1
2
3
4
| list = ["a", "b", "c", "d"]
for i in 0..3
print "第", i+1,"个元素是",list[i],"。\n"
end
|
代码清单 13.2:sum_list.rb
1
2
3
4
5
6
| list = [1, 3, 5, 7, 9]
sum = 0
for i in 0..4
sum += list[i]
end
print "合计:",sum,"\n"
|
代码清单 13.3:sum_list2.rb
1
2
3
4
5
6
| list = [1, 3, 5, 7, 9]
sum = 0
list.each do |elem|
sum += elem
end
print "合计:",sum,"\n"
|
代码清单 13.4:list2.rb
1
2
3
4
| list = ["a", "b", "c", "d"]
list.each_with_index do |elem, i|
print "第", i+1,"个元素是",elem,"。\n"
end
|
代码清单 13.5:sum_with_each.rb
1
2
3
4
5
6
7
8
9
10
11
| ary1 = [1, 2, 3, 4, 5]
ary2 = [10, 20, 30, 40, 50]
ary3 = [100, 200, 300, 400, 500]
i = 0
result = []
while i < ary1.length
result << ary1[i] + ary2[i] + ary3[i]
i += 1
end
p result #=> [111, 222, 333, 444, 555]
|
代码清单 13.6:sum_with_zip.rb
1
2
3
4
5
6
7
8
9
| ary1 = [1, 2, 3, 4, 5]
ary2 = [10, 20, 30, 40, 50]
ary3 = [100, 200, 300, 400, 500]
result = []
ary1.zip(ary2, ary3) do |a, b, c|
result << a + b + c
end
p result #=> [111, 222, 333, 444, 555]
|
第 14 章
代码清单 14.1:frozen_string.rb
1
2
3
4
| # frozen-string-literal: true
str = "Ruby"
p str.upcase!
|
第 15 章
代码清单 15.1:word_count.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
| # 计算单词数量
count = Hash.new(0)
## 统计单词
File.open(ARGV[0]) do |f|
f.each_line do |line|
words = line.split
words.each do |word|
count[word] += 1
end
end
end
## 输出结果
count.sort{|a, b|
a[1] <=> b[1]
}.each do |key, value|
print "#{key}: #{value}\n"
end
|
第 16 章
代码清单 16.1:scan1.rb
1
2
3
| "abracatabra".scan(/.a/) do |matched|
p matched
end
|
代码清单 16.2:scan2.rb
1
2
3
| "abracatabra".scan(/(.)(a)/) do |matched|
p matched
end
|
代码清单 16.3:scan3.rb
1
2
3
| "abracatabra".scan(/(.)(a)/) do |a, b|
p a+"-"+b
end
|
代码清单 16.4:url_match.rb
1
2
3
| str = "http://www.ruby-lang.org/ja/"
%r|http://([^/]*)/| =~ str
print "server address: ", $1, "\n"
|
第 17 章
代码清单 17.1:out.rb
1
2
3
4
| 3.times do |i|
$stdout.puts "#{Random.rand}\n" # 标准输出
$stderr.puts "已经输出了#{i+1}次\n" # 标准错误输出
end
|
代码清单 17.2:tty.rb
1
2
3
4
5
| if $stdin.tty?
print "Stdin is a TTY.\n"
else
print "Stdin is not a TTY.\n"
end
|
代码清单 17.3:stdout_put.rb
1
| $stdout.puts "String", :Symbol, 1/100r
|
代码清单 17.4:stdout_putc.rb
1
2
3
| $stdout.putc(82) # 82是“R”的ASCII码
$stdout.putc("Ruby")
$stdout.putc("\n")
|
代码清单 17.5:test_buffering1.rb
1
2
3
4
5
6
7
8
9
10
| filename = "buffering.txt"
File.open(filename, "w") do |file|
3.times do |i|
# 检查每5个字节写入后文件的大小
file.write("a" * 5)
puts "第#{i+1}次: #{File.size(filename)}"
end
end
puts "结束: #{File.size(filename)}" #=> 再检查一次
p File.read(filename) #=> 确认输出
|
代码清单 17.6:test_buffering2.rb
1
2
3
4
5
6
7
8
9
10
11
| filename = "buffering.txt"
File.open(filename, "w") do |file|
3.times do |i|
# 检查每5个字节写入后文件的大小
file.write("a" * 5)
file.flush # 写入数据
puts "第#{i+1}次: #{File.size(filename)}"
end
end
puts "结束后: #{File.size(filename)}" # 再检查一次
p File.read(filename) # 确认输出
|
代码清单 17.7:test_buffering3.rb
1
2
3
4
5
6
7
8
9
10
11
| filename = "buffering.txt"
File.open(filename, "w") do |file|
file.sync = true # 同步写入
3.times do |i|
# 检查每写入5个字节后文件的大小
file.write("a" * 5)
puts "第#{i+1}次: #{File.size(filename)}"
end
end
puts "结束后: #{File.size(filename)}" # 再检查一次
p File.read(filename) # 确认输出
|
代码清单 17.8:simple_grep_gz.rb
1
2
3
4
5
6
7
8
9
10
11
12
| pattern = Regexp.new(ARGV[0])
filename = ARGV[1]
if /.gz$/ =~ filename
file = IO.popen("zcat #{filename}")
else
file = File.open(filename)
end
file.each_line do |text|
if pattern =~ text
print text
end
end
|
代码清单 17.9:read_uri.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
| require "open-uri"
# 通过HTTP读取数据
open("http://www.ruby-lang.org/zh_cn/") do |io|
puts io.read # 将Ruby的官方网页输出到控制台
end
# 通过FTP读取数据
filename = "ruby-2.3.0.tar.gz"
url = "ftp://www.ruby-lang.org/pub/ruby/2.3/#{filename}"
open(url) do |io|
File.binwrite(filename, io.read) # 写入文件
end
|
代码清单 17.10:read_uri_ja.rb
1
2
3
4
5
6
7
8
| require "open-uri"
options = {
"Accept-Language" => "ja, en;q=0.5",
}
open("http://www.ruby-lang.org", options){|io|
puts io.read
}
|
代码清单 17.11:stringio_puts.rb
1
2
3
4
5
6
7
8
| require "stringio"
io = StringIO.new
io.puts("A")
io.puts("B")
io.puts("C")
io.rewind
p io.read #=> "A\nB\nC\n"
|
代码清单 17.12:stringio_gets.rb
1
2
3
4
5
6
| require "stringio"
io = StringIO.new("A\nB\nC\n")
p io.gets #=> "A\n"
p io.gets #=> "B\n"
p io.gets #=> "C\n"
|
第 18 章
代码清单 18.1:traverse.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
| def traverse(path)
if File.directory?(path) # 如果是目录
dir = Dir.open(path)
while name = dir.read
next if name == "." # ※
next if name == ".." # ※
traverse(path + "/" + name)
end
dir.close
else
process_file(path) # 处理文件
end
end
def process_file(path)
puts path # 输出结果
end
traverse(ARGV[0])
|
代码清单 18.2:traverse_by_glob.rb
1
2
3
4
5
6
7
| def traverse(path)
Dir.glob(["#{path}/**/*", "#{path}/**/.*"]).each do |name|
unless File.directory?(name)
process_file(name)
end
end
end
|
代码清单 18.3:listdir.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
| require 'find'
IGNORES = [ /^\./, /^CVS$/, /^RCS$/ ]
def listdir(top)
Find.find(top) do |path|
if FileTest.directory?(path) # 如果path是目录
dir, base = File.split(path)
IGNORES.each do |re|
if re =~ base # 需要忽略的目录
Find.prune # 忽略该目录下的内容的查找
end
end
puts path # 输出结果
end
end
end
listdir(ARGV[0])
|
第 19 章
无代码清单。
第 20 章
无代码清单。
第 21 章
代码清单 21.1:power_of.rb
1
2
3
4
5
6
7
8
| def power_of(n)
lambda do |x|
return x ** n
end
end
cube = power_of(3)
p cube.call(5) #=> 125
|
代码清单 21.2:prefix.rb
1
2
3
4
5
6
7
8
9
10
11
12
| def prefix(ary, obj)
result = [] # 初始化结果数组
ary.each do |item| # 逐个检查元素
result << item # 将元素追加到结果数组中
if item == obj # 如果元素与条件一致
return result # 返回结果数组
end
end
return result # 所有元素检查完毕的时候
end
prefix([1, 2, 3, 4, 5], 3) #=> [1, 2, 3]
|
代码清单 21.3:total2.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
| def total2(from, to, &block)
result = 0 # 合计值
from.upto(to) do |num| # 处理从from到to的值
if block # 如果有块的话
result += # 累加经过块处理的值
block.call(num)
else # 如果没有块的话
result += num # 直接累加
end
end
return result # 返回方法的结果
end
p total2(1, 10) # 从1到10的和 => 55
p total2(1, 10){|num| num ** 2 } # 从1到10的2次冥的和 => 385
|
代码清单 21.4:counter_proc.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
| def counter
c = 0 # 初始化计数器
Proc.new do # 每调用1次call方法,计数器加1
c += 1 # 返回加1后的Proc对象
end
end
# 创建计数器c1并计数
c1 = counter
p c1.call #=> 1
p c1.call #=> 2
p c1.call #=> 3
# 创建计数器c2并计数
c2 = counter # 创建计数器c2
p c2.call #=> 1
p c2.call #=> 2
# 再次用c1计数
p c1.call #=> 4
|
代码清单 21.5:proc_source_location.rb
1
2
3
4
5
| prc0 = Proc.new{ nil }
prc1 = Proc.new{|a| a }
p prc0.source_location
p prc1.source_location
|
第 22 章
代码清单 22.1:get_kongyiji.rb
1
2
3
4
5
6
7
8
9
10
| require "open-uri"
url = "http://www.ituring.com.cn/article/274457"
filename = "kongyiji.html"
File.open(filename, "wb") do |f|
text = open(url, "r:utf-8").read
f.write text # UTF8环境使用此段代码
#f.write text.encode("GB18030") # 简体中文环境(中文简体版Windows)使用此段代码
end
|
代码清单 22.2:cut_kongyiji.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
| htmlfile = "kongyiji.html"
textfile = "kongyiji.txt"
html = File.read(htmlfile) #html = File.read(htmlfile, mode: "rb:GB18030") # 译者注:简体中文环境(中文简体版Windows)使用此段代码
File.open(textfile, "w") do |f|
in_header = true
html.each_line do |line|
if in_header && /<div class="post-text">/ !~ line
next
else
in_header = false
end
break if /<div class="copyright-announce">/ =~ line
f.write line
end
end
|
代码清单 22.3:cut_kongyiji2.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
| require 'cgi/util'
htmlfile = "kongyiji.html"
textfile = "kongyiji.txt"
html = File.read(htmlfile) #html = File.read(htmlfile, mode: "rb:GB18030") # 译者注:简体中文环境(中文简体版Windows)使用此段代码
File.open(textfile, "w") do |f|
in_header = true
html.each_line do |line|
if in_header && /<div class="post-text">/ !~ line
next
else
in_header = false
end
break if /<div class="copyright-announce">/ =~ line
line.gsub!(/<[^>]+>/, '')
esc_line = CGI.unescapeHTML(line)
f.write esc_line
end
end
|
代码清单 22.4:simple_grep.rb
1
2
3
4
5
6
7
8
9
10
| pattern = Regexp.new(ARGV[0])
filename = ARGV[1]
File.open(filename) do |file|
file.each_line do |line|
if pattern =~ line
print line
end
end
end
|
代码清单 22.5:simple_scan.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
| pattern = Regexp.new(ARGV[0])
filename = ARGV[1]
count = 0
File.open(filename) do |file|
file.each_line do |line|
if pattern =~ line
line.scan(pattern) do |s|
count += 1
end
print line
end
end
end
puts "count: #{count}"
|
代码清单 22.6:simple_count.rb
1
2
3
4
5
6
7
8
| pattern = Regexp.new(ARGV[0])
filename = ARGV[1]
count = 0
File.read(filename).scan(pattern) do |s|
count += 1
end
puts "count: #{count}"
|
代码清单 22.7:simple_match.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
| pattern = Regexp.new(ARGV[0])
filename = ARGV[1]
count = 0
File.open(filename) do |file|
file.each_line do |line|
if pattern =~ line
line.scan(pattern) do |s|
count += 1
end
print line.gsub(pattern){|str| "<<#{str}>>"}
end
end
end
puts "count: #{count}"
|
代码清单 22.8:simple_match2.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
| pattern = Regexp.new("(.{10})("+ARGV[0]+")(.{10})")
filename = ARGV[1]
count = 0
File.open(filename) do |file|
file.each_line do |line|
line.scan(pattern) do |s|
puts "#{s[0]}<<#{s[1]}>>#{s[2]}"
count += 1
end
end
end
puts "count: #{count}"
|
代码清单 22.9:simple_match3.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
| pattern = Regexp.new(ARGV[0])
filename = ARGV[1]
count = 0
File.open(filename) do |file|
file.each_line do |line|
line.scan(pattern) do |s|
pre = $`
post = $'
puts "#{pre[-10,10]}<<#{s}>>#{post[0,10]}"
count += 1
end
end
end
puts "count: #{count}"
|
代码清单 22.10:simple_match4.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
| pattern = Regexp.new(ARGV[0])
filename = ARGV[1]
len = ARGV[2].to_i
count = 0
File.open(filename) do |file|
file.each_line do |line|
line.scan(pattern) do |s|
pre = $`
post = $'
puts "#{pre[-len,len]}<<#{s}>>#{post[0,len]}"
count += 1
end
end
end
puts "count: #{count}"
|
第 23 章
代码清单 23.1:read_csv.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
| require "csv" # 使用csv库
code = ARGV[0] # 读取参数
start_time = Time.now # 获取操作开始时间
# 将Shift_jis转换为UTF-8后打开CSV文件
CSV.open("KEN_ALL.CSV", "r:Shift_jis:UTF-8") do |csv|
csv.each do |record|
# 邮政编码与参数指定的一致则输出该记录
puts record.join(" ") if record[2] == code
end
end
p Time.now - start_time # 输出结束时间与开始时间之差
|
代码清单 23.2:jzipcode.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
| require 'sqlite3'
require "csv"
class JZipCode
CSV_COLUMN = {code: 2, pref: 6, city: 7, addr: 8}
def initialize(dbfile)
@dbfile = dbfile
end
def create(zipfile)
return if File.exist?(@dbfile)
SQLite3::Database.open(@dbfile) do |db|
db.execute(<<-SQL)
CREATE TABLE IF NOT EXISTS zip_codes
(code TEXT, pref TEXT, city TEXT, addr TEXT, alladdr TEXT)
SQL
db.execute("BEGIN TRANSACTION")
CSV.open(zipfile, "r:Shift_JIS:UTF-8") do |csv|
csv.each do |rec|
data = Hash.new
CSV_COLUMN.each{|key, index| data[key] = rec[index] }
data[:alladdr] = data[:pref] + data[:city] + data[:addr]
db.execute(<<-SQL, data)
INSERT INTO zip_codes VALUES
(:code, :pref, :city, :addr, :alladdr)
SQL
end
end
db.execute("COMMIT TRANSACTION")
end
return true
end
def find_by_code(code)
ret = []
SQLite3::Database.open(@dbfile) do |db|
db.execute(<<-SQL, code){|row| ret << row.join(" ") }
SELECT code, alladdr
FROM zip_codes
WHERE code = ?
SQL
end
return ret.map{|line| line + "\n"}.join
end
def find_by_address(addr)
ret = []
SQLite3::Database.open(@dbfile) do |db|
like = "%#{addr}%"
db.execute(<<-SQL, like){|row| ret << row.join(" ") }
SELECT code, alladdr
FROM zip_codes
WHERE alladdr LIKE ?
SQL
end
return ret.map{|line| line + "\n"}.join
end
end
if __FILE__ == $0
dbfile = "jzipcode.db"
jzipcode = JZipCode.new(dbfile)
jzipcode.create("KEN_ALL.CSV")
puts jzipcode.find_by_code("3210202")
puts jzipcode.find_by_address("猫屋敷")
end
|