# 【Ruby 块】
=begin
1 块由大量代码构成
2 块中代码包含在{}内
3 从与其相同名称的函数调用
4 可以使用yield语句调用块
=end
def test
p '在test方法内'
yield
p '又回到了test方法内'
yield
end
test {p '你在块内'}
#也可以传递由参数的yield
def test
yield 5
p '在方法内'
yield 100
end
test {|i| p "你在块#{i}内"}
# 传递多个参数
def test
yield 5,100
p '在方法内'
yield 6,90
end
test {|a,b| p "你在块#{b}和#{a}内"}
=begin
"你在块100内"
"你在块100和5内"
"在方法内"
"你在块90和6内"
=end
#另一种调用块的方式
def test(&block)
block.call
end
test {p 'hello world!'} #"hello world!"
# 【【运算符】】
#【比较运算符】
=begin
<=> 联合比较运算符,相等返回0;第一个数大返回1;第二个数大返回-1
== 值相等
.eql? 类型相同且值相等
.equal? 是否具有相同的对象ID(内存地址是否相同)
=== 判断是否具有相同的类,或父类 判断两个实例对象是否具有血缘关系。另一种说法 判断case 语句的 when 子句内的 相等
=end
puts 1 == 1.0 #true
puts 1 === 1.0 #true
puts 1 === "abc" #false
puts (1...10) === 5 #true
puts (1...10) === 3 #true
puts (1..3) === 3 #true
puts (1...3) === 3 #false
puts 1.eql?(1) #true
puts 1.eql?(1.0) #false
puts 1.equal?(1) #true
puts 1.equal?(1.0) #false
a = 1
b = a
A = 'ABC'
B = A
AA = "A"
BB = AA + ""
print "a's ID : ",a.object_id,"\n"
print "b's ID : ",b.object_id,"\n"
print "A's ID : ",A.object_id,"\n"
print "B's ID : ",B.object_id,"\n"
print "AA's ID : ",AA.object_id,"\n"
print "BB's ID : ",BB.object_id,"\n"
print 'AA == BB : ',AA == BB,"\n"
print 'AA.eql?(BB) : ',AA.eql?(BB),"\n"
print 'AA.equal?(BB) : ',AA.equal?(BB),"\n"
print 'a.equal?(1) : ', a.equal?(1),"\n"
print 'b.equal?(1) : ',b.equal?(1),"\n"
print 'a.equal?(b) : ',a.equal?(b),"\n"
print '1.equal?(a) : ',1.equal?(a),"\n"
print '1.equal?(b) : ',1.equal?(b),"\n"
print 'A.equal?(B) : ',A.equal?(B),"\n"
=begin
a's ID : 3
b's ID : 3
A's ID : 70215304749280
B's ID : 70215304749280
AA's ID : 70215304749260
BB's ID : 70215304749180
AA == BB : true
AA.eql?(BB) : true
AA.equal?(BB) : false
a.equal?(1) : true
b.equal?(1) : true
a.equal?(b) : true
1.equal?(a) : true
1.equal?(b) : true
A.equal?(B) : true
=end
#【Ruby defined运算符】 以方法调用的形式判断传递的表达式是否已定义。返回表达式的描述字符串,如果表达式未定义则返回nil.
foo = 42
puts defined? foo #local-variable
puts defined? $_ #global-variable
puts defined? bar #打印了一个空行
puts defined? puts #method
puts defined? puts(var)#打印了一个空行
puts defined? unpack #打印了一个空行
#【Ruby 中的.运算符 和 :: 运算符】通过在方法名称前加上类或模块名称和 . 来调用类或模块中的方法。你可以使用类或模块名称和两个冒号 :: 来引用类或模块中的常量
#例子
# 定义在主Object类上的常量
MR_COUNT = 0
module Foo
MR_COUNT = 0
#设置全局计数为1
::MR_COUNT = 1
#设置局部计数为2
MR_COUNT = 2
end
puts MR_COUNT #1
puts Foo::MR_COUNT #2
#例子
CONST = ' out there '
class Inside_one
end
#【Ruby 点运算符 "." 和双冒号运算符 "::"】
=begin
你可以通过在方法名称前加上类或模块名称和 . 来调用类或模块中的方法。你可以使用类或模块名称和两个冒号 :: 来引用类或模块中的常量。
:: 是一元运算符,允许在类或模块内定义常量、实例方法和类方法,可以从类或模块外的任何地方进行访问。
请记住:在 Ruby 中,类和方法也可以被当作常量。
你只需要在表达式的常量名前加上 :: 前缀,即可返回适当的类或模块对象。
如果 :: 前的表达式为类或模块名称,则返回该类或模块内对应的常量值;如果 :: 前未没有前缀表达式,则返回主Object类中对应的常量值。 。
=end
CONST = ' out there'
class Inside_one
CONST = proc{' in there'}
def where_is_my_CONST
::CONST + ' inside one'
end
end
class Inside_two
CONST = ' inside two'
def where_is_my_CONST
CONST
end
end
puts Inside_one.new.where_is_my_CONST # out there inside one
puts Inside_two.new.where_is_my_CONST # inside two
puts Object::CONST + Inside_two::CONST # out there inside two
puts Inside_two::CONST + CONST # inside two out there
puts Inside_one::CONST ##<Proc:0x15d0c81b@D:/DATA/wangxue/RubymineProjects/untitled/class_and_obj.rb:5>
puts Inside_one::CONST.call + Inside_two::CONST # in there inside two
# 【模块】
=begin
1。 类似于类,但有不同
2。 模块不能实例化
3。 模块没有子类
4。 模块只能被另一个模块定义
=end
# 例子 同级目录下有 trip.rb 里面有模块Trip ;同级目录下有 moral.rb 里面有模块 Moral
$LOAD_PATH << '.' # 【备注】从当前目录中搜索被引用的文件。如果不像使用$LOAD_PATH 可使用 require_relative 来从一个相对目录引用文件。
require 'trip'
require 'moral'
y = Trip.sin(Trip::PI/4)
wrongdoing = Moral.sin(Moral::VERY_BAD)
# 例子 同级下有support.rb ,里面有模块 Week
$LOAD_PATH << '.'
require 'support'
class Decade
include Week
num_of_year = 10
def num_of_months
puts Week::FIRST_DAY
numbers = 10*12
puts numbers
end
end
d1 = Decade.new
puts Week::FIRST_DAY
Week.week_in_month
Week.week_in_year
d1.num_of_months
=begin
Sunday
you have four weeks in a month
you have 52 weeks in a year
Sunday
120
=end
# 【Ruby 中的 Mixins】
=begin
面向对象的概念。
当一个类可以从多个父类继承类的特性时,该类显示为多重继承。
Ruby不能直接支持多重继承,但是Ruby的模块有另一个神奇的功能。它几乎消除了多重继承的需要,一共了一种名为mixin的装置。
Ruby没有真正实现多重继承,而是采用成为mixin技术作为替代品,将模块include到类定义中,模块中的方法就mix进了类中。
=end
#例子
module A
def a1
end
def a2
end
end
module B
def b1
end
def b2
end
end
class Sample
include A
include B
def s1
end
end
samp = Sample.new
samp.a1
samp.a2
samp.b1
samp.b2
samp.s1
# 【【Ruby字符串】】String
# 例子
x,y,z = 12,36,72
puts "x 的值:#{x}"
puts "x + y 的值: #{x + y}"
puts "x + y + z 的平均值: #{(x + y + z)/3}"
=begin
x 的值:12
x + y 的值: 48
x + y + z 的平均值: 40
=end
# 【字符串的内建方法】
# 例子
myStr = String.new("THIS IS TEST")
foo = myStr.downcase()
puts "#{foo}"
puts foo
=begin
this is test
this is test
=end
# 【字符串的公共方法】
=begin
序号 方法 & 描述
1 str % arg
使用格式规范格式化字符串。如果 arg 包含一个以上的替代,那么 arg 必须是一个数组。如需了解更多格式规范的信息,请查看"内核模块"下的 sprintf。
2 str * integer
返回一个包含 integer 个 str 的新的字符串。换句话说,str 被重复了 integer 次。
3 str + other_str
连接 other_str 到 str。
4 str << obj
连接一个对象到字符串。如果对象是范围为 0.255 之间的固定数字 Fixnum,则它会被转换为一个字符。把它与 concat 进行比较。
5 str <=> other_str
把 str 与 other_str 进行比较,返回 -1(小于)、0(等于)或 1(大于)。比较是区分大小写的。
6 str == obj
检查 str 和 obj 的相等性。如果 obj 不是字符串,则返回 false,如果 str <=> obj,则返回 true,返回 0。
7 str =~ obj
根据正则表达式模式 obj 匹配 str。返回匹配开始的位置,否则返回 false。
8 str[position] # 注意返回的是ASCII码而不是字符
str[start, length]
str[start..end]
str[start...end]
使用索引截取子串
9 str.capitalize
把字符串转换为大写字母显示。
10 str.capitalize!
与 capitalize 相同,但是 str 会发生变化并返回。
11 str.casecmp
不区分大小写的字符串比较。
12 str.center
居中字符串。
13 str.chomp
从字符串末尾移除记录分隔符($/),通常是 \n。如果没有记录分隔符,则不进行任何操作。
14 str.chomp!
与 chomp 相同,但是 str 会发生变化并返回。
15 str.chop
移除 str 中的最后一个字符。
16 str.chop!
与 chop 相同,但是 str 会发生变化并返回。
17 str.concat(other_str)
连接 other_str 到 str。
18 str.count(str, ...)
给一个或多个字符集计数。如果有多个字符集,则给这些集合的交集计数。
19 str.crypt(other_str)
对 str 应用单向加密哈希。参数是两个字符长的字符串,每个字符的范围为 a.z、 A.Z、 0.9、 . 或 /。
20 str.delete(other_str, ...)
返回 str 的副本,参数交集中的所有字符会被删除。
21 str.delete!(other_str, ...)
与 delete 相同,但是 str 会发生变化并返回。
22 str.downcase
返回 str 的副本,所有的大写字母会被替换为小写字母。
23 str.downcase!
与 downcase 相同,但是 str 会发生变化并返回。
24 str.dump
返回 str 的版本,所有的非打印字符被替换为 \nnn 符号,所有的特殊字符被转义。
25 str.each(separator=$/) { |substr| block }
使用参数作为记录分隔符(默认是 $/)分隔 str,传递每个子字符串给被提供的块。
26 str.each_byte { |fixnum| block }
传递 str 的每个字节给 block,以字节的十进制表示法返回每个字节。
27 str.each_line(separator=$/) { |substr| block }
使用参数作为记录分隔符(默认是 $/)分隔 str,传递每个子字符串给被提供的 block。
28 str.empty?
如果 str 为空(即长度为 0),则返回 true。
29 str.eql?(other)
如果两个字符串有相同的长度和内容,则这两个字符串相等。
30 str.gsub(pattern, replacement) [or]
str.gsub(pattern) { |match| block }
返回 str 的副本,pattern 的所有出现都替换为 replacement 或 block 的值。pattern 通常是一个正则表达式 Regexp;如果是一个字符串 String,则没有正则表达式元字符被解释(即,/\d/ 将匹配一个数字,但 '\d' 将匹配一个反斜杠后跟一个 'd')。
31 str[fixnum] [or] str[fixnum,fixnum] [or] str[range] [or] str[regexp] [or] str[regexp, fixnum] [or] str[other_str]
使用下列的参数引用 str:参数为一个 Fixnum,则返回 fixnum 的字符编码;参数为两个 Fixnum,则返回一个从偏移(第一个 fixnum)开始截至到长度(第二个 fixnum)为止的子字符串;参数为 range,则返回该范围内的一个子字符串;参数为 regexp,则返回匹配字符串的部分;参数为带有 fixnum 的 regexp,则返回 fixnum 位置的匹配数据;参数为 other_str,则返回匹配 other_str 的子字符串。一个负数的 Fixnum 从字符串的末尾 -1 开始。
32 str[fixnum] = fixnum [or] str[fixnum] = new_str [or] str[fixnum, fixnum] = new_str [or] str[range] = aString [or] str[regexp] =new_str [or] str[regexp, fixnum] =new_str [or] str[other_str] = new_str ]
替换整个字符串或部分字符串。与 slice! 同义。
33 str.gsub!(pattern, replacement) [or] str.gsub!(pattern) { |match| block }
执行 String#gsub 的替换,返回 str,如果没有替换被执行则返回 nil。
34 str.hash
返回一个基于字符串长度和内容的哈希。
35 str.hex
把 str 的前导字符当作十六进制数字的字符串(一个可选的符号和一个可选的 0x),并返回相对应的数字。如果错误则返回零。
36 str.include? other_str [or] str.include? fixnum
如果 str 包含给定的字符串或字符,则返回 true。
37 str.index(substring [, offset]) [or]
str.index(fixnum [, offset]) [or]
str.index(regexp [, offset])
返回给定子字符串、字符(fixnum)或模式(regexp)在 str 中第一次出现的索引。如果未找到则返回 nil。如果提供了第二个参数,则指定在字符串中开始搜索的位置。
38 str.insert(index, other_str)
在给定索引的字符前插入 other_str,修改 str。负值索引从字符串的末尾开始计数,并在给定字符后插入。其意图是在给定的索引处开始插入一个字符串。
39 str.inspect
返回 str 的可打印版本,带有转义的特殊字符。
40 str.intern [or] str.to_sym
返回与 str 相对应的符号,如果之前不存在,则创建符号。
41 str.length
返回 str 的长度。把它与 size 进行比较。
42 str.ljust(integer, padstr=' ')
如果 integer 大于 str 的长度,则返回长度为 integer 的新字符串,新字符串以 str 左对齐,并以 padstr 作为填充。否则,返回 str。
43 str.lstrip
返回 str 的副本,移除了前导的空格。
44 str.lstrip!
从 str 中移除前导的空格,如果没有变化则返回 nil。
45 str.match(pattern)
如果 pattern 不是正则表达式,则把 pattern 转换为正则表达式 Regexp,然后在 str 上调用它的匹配方法。
46 str.oct
把 str 的前导字符当作十进制数字的字符串(一个可选的符号),并返回相对应的数字。如果转换失败,则返回 0。
47 str.replace(other_str)
把 str 中的内容替换为 other_str 中的相对应的值。
48 str.reverse
返回一个新字符串,新字符串是 str 的倒序。
49 str.reverse!
逆转 str,str 会发生变化并返回。
50 str.rindex(substring [, fixnum]) [or]
str.rindex(fixnum [, fixnum]) [or]
str.rindex(regexp [, fixnum])
返回给定子字符串、字符(fixnum)或模式(regexp)在 str 中最后一次出现的索引。如果未找到则返回 nil。如果提供了第二个参数,则指定在字符串中结束搜索的位置。超出该点的字符将不被考虑。
51 str.rjust(integer, padstr=' ')
如果 integer 大于 str 的长度,则返回长度为 integer 的新字符串,新字符串以 str 右对齐,并以 padstr 作为填充。否则,返回 str。
52 str.rstrip
返回 str 的副本,移除了尾随的空格。
53 str.rstrip!
从 str 中移除尾随的空格,如果没有变化则返回 nil。
54 str.scan(pattern) [or]
str.scan(pattern) { |match, ...| block }
两种形式匹配 pattern(可以是一个正则表达式 Regexp 或一个字符串 String)遍历 str。针对每个匹配,会生成一个结果,结果会添加到结果数组中或传递给 block。如果 pattern 不包含分组,则每个独立的结果由匹配的字符串、$& 组成。如果 pattern 包含分组,每个独立的结果是一个包含每个分组入口的数组。
55 str.slice(fixnum) [or] str.slice(fixnum, fixnum) [or]
str.slice(range) [or] str.slice(regexp) [or]
str.slice(regexp, fixnum) [or] str.slice(other_str)
See str[fixnum], etc.
str.slice!(fixnum) [or] str.slice!(fixnum, fixnum) [or] str.slice!(range) [or] str.slice!(regexp) [or] str.slice!(other_str)
从 str 中删除指定的部分,并返回删除的部分。如果值超出范围,参数带有 Fixnum 的形式,将生成一个 IndexError。参数为 range 的形式,将生成一个 RangeError,参数为 Regexp 和 String 的形式,将忽略执行动作。
56 str.split(pattern=$;, [limit])
基于分隔符,把 str 分成子字符串,并返回这些子字符串的数组。
如果 pattern 是一个字符串 String,那么在分割 str 时,它将作为分隔符使用。如果 pattern 是一个单一的空格,那么 str 是基于空格进行分割,会忽略前导空格和连续空格字符。
如果 pattern 是一个正则表达式 Regexp,则 str 在 pattern 匹配的地方被分割。当 pattern 匹配一个玲长度的字符串时,str 被分割成单个字符。
如果省略了 pattern 参数,则使用 $; 的值。如果 $; 为 nil(默认的),str 基于空格进行分割,就像是指定了 ` ` 作为分隔符一样。
如果省略了 limit 参数,会抑制尾随的 null 字段。如果 limit 是一个正数,则最多返回该数量的字段(如果 limit 为 1,则返回整个字符串作为数组中的唯一入口)。如果 limit 是一个负数,则返回的字段数量不限制,且不抑制尾随的 null 字段。
57 str.squeeze([other_str]*)
使用为 String#count 描述的程序从 other_str 参数建立一系列字符。返回一个新的字符串,其中集合中出现的相同的字符会被替换为单个字符。如果没有给出参数,则所有相同的字符都被替换为单个字符。
58 str.squeeze!([other_str]*)
与 squeeze 相同,但是 str 会发生变化并返回,如果没有变化则返回 nil。
59 str.strip
返回 str 的副本,移除了前导的空格和尾随的空格。
60 str.strip!
从 str 中移除前导的空格和尾随的空格,如果没有变化则返回 nil。
61 str.sub(pattern, replacement) [or]
str.sub(pattern) { |match| block }
返回 str 的副本,pattern 的第一次出现会被替换为 replacement 或 block 的值。pattern 通常是一个正则表达式 Regexp;如果是一个字符串 String,则没有正则表达式元字符被解释。
62 str.sub!(pattern, replacement) [or]
str.sub!(pattern) { |match| block }
执行 String#sub 替换,并返回 str,如果没有替换执行,则返回 nil。
63 str.succ [or] str.next
返回 str 的继承。
64 str.succ! [or] str.next!
相当于 String#succ,但是 str 会发生变化并返回。
65 str.sum(n=16)
返回 str 中字符的 n-bit 校验和,其中 n 是可选的 Fixnum 参数,默认为 16。结果是简单地把 str 中每个字符的二进制值的总和,以 2n - 1 为模。这不是一个特别好的校验和。
66 str.swapcase
返回 str 的副本,所有的大写字母转换为小写字母,所有的小写字母转换为大写字母。
67 str.swapcase!
相当于 String#swapcase,但是 str 会发生变化并返回,如果没有变化则返回 nil。
68 str.to_f
返回把 str 中的前导字符解释为浮点数的结果。超出有效数字的末尾的多余字符会被忽略。如果在 str 的开头没有有效数字,则返回 0.0。该方法不会生成异常。
69 str.to_i(base=10)
返回把 str 中的前导字符解释为整数基数(基数为 2、 8、 10 或 16)的结果。超出有效数字的末尾的多余字符会被忽略。如果在 str 的开头没有有效数字,则返回 0。该方法不会生成异常。
70 str.to_s [or] str.to_str
返回接收的值。
71 str.tr(from_str, to_str)
返回 str 的副本,把 from_str 中的字符替换为 to_str 中相对应的字符。如果 to_str 比 from_str 短,那么它会以最后一个字符进行填充。两个字符串都可以使用 c1.c2 符号表示字符的范围。如果 from_str 以 ^ 开头,则表示除了所列出的字符以外的所有字符。
72 str.tr!(from_str, to_str)
相当于 String#tr,但是 str 会发生变化并返回,如果没有变化则返回 nil。
73 str.tr_s(from_str, to_str)
把 str 按照 String#tr 描述的规则进行处理,然后移除会影响翻译的重复字符。
74 str.tr_s!(from_str, to_str)
相当于 String#tr_s,但是 str 会发生变化并返回,如果没有变化则返回 nil。
75 str.unpack(format)
根据 format 字符串解码 str(可能包含二进制数据),返回被提取的每个值的数组。format 字符由一系列单字符指令组成。每个指令后可以跟着一个数字,表示重复该指令的次数。星号(*)将使用所有剩余的元素。指令 sSiIlL 每个后可能都跟着一个下划线(_),为指定类型使用底层平台的本地尺寸大小,否则使用独立于平台的一致的尺寸大小。format 字符串中的空格会被忽略。
76 str.upcase
返回 str 的副本,所有的小写字母会被替换为大写字母。操作是环境不敏感的,只有字符 a 到 z 会受影响。
77 str.upcase!
改变 str 的内容为大写,如果没有变化则返回 nil。
78 str.upto(other_str) { |s| block }
遍历连续值,以 str 开始,以 other_str 结束(包含),轮流传递每个值给 block。String#succ 方法用于生成每个值。
=end
# 【字符串 unpack 指令】
=begin
指令 返回 描述
A String 移除尾随的 null 和空格。
a String 字符串。
B String 从每个字符中提取位(首先是最高有效位)。
b String 从每个字符中提取位(首先是最低有效位)。
C Fixnum 提取一个字符作为无符号整数。
c Fixnum 提取一个字符作为整数。
D, d Float 把 sizeof(double) 长度的字符当作原生的 double。
E Float 把 sizeof(double) 长度的字符当作 littleendian 字节顺序的 double。
e Float 把 sizeof(float) 长度的字符当作 littleendian 字节顺序的 float。
F, f Float 把 sizeof(float) 长度的字符当作原生的 float。
G Float 把 sizeof(double) 长度的字符当作 network 字节顺序的 double。
g Float 把 sizeof(float) 长度的字符当作 network 字节顺序的 float。
H String 从每个字符中提取十六进制(首先是最高有效位)。
h String 从每个字符中提取十六进制(首先是最低有效位)。
I Integer 把 sizeof(int) 长度(通过 _ 修改)的连续字符当作原生的 integer。
i Integer 把 sizeof(int) 长度(通过 _ 修改)的连续字符当作有符号的原生的 integer。
L Integer 把四个(通过 _ 修改)连续字符当作无符号的原生的 long integer。
l Integer 把四个(通过 _ 修改)连续字符当作有符号的原生的 long integer。
M String 引用可打印的。
m String Base64 编码。
N Integer 把四个字符当作 network 字节顺序的无符号的 long。
n Fixnum 把两个字符当作 network 字节顺序的无符号的 short。
P String 把 sizeof(char *) 长度的字符当作指针,并从引用的位置返回 \emph{len} 字符。
p String 把 sizeof(char *) 长度的字符当作一个空结束字符的指针。
Q Integer 把八个字符当作无符号的 quad word(64 位)。
q Integer 把八个字符当作有符号的 quad word(64 位)。
S Fixnum 把两个(如果使用 _ 则不同)连续字符当作 native 字节顺序的无符号的 short。
s Fixnum 把两个(如果使用 _ 则不同)连续字符当作 native 字节顺序的有符号的 short。
U Integer UTF-8 字符,作为无符号整数。
u String UU 编码。
V Fixnum 把四个字符当作 little-endian 字节顺序的无符号的 long。
v Fixnum 把两个字符当作 little-endian 字节顺序的无符号的 short。
w Integer BER 压缩的整数。
X 向后跳过一个字符。
x 向前跳过一个字符。
Z String 和 * 一起使用,移除尾随的 null 直到第一个 null。
@ 跳过 length 参数给定的偏移量。
实例
尝试下面的实例,解压各种数据。
"abc \0\0abc \0\0".unpack('A6Z6') #=> ["abc", "abc "]
"abc \0\0".unpack('a3a3') #=> ["abc", " \000\000"]
"abc \0abc \0".unpack('Z*Z*') #=> ["abc ", "abc "]
"aa".unpack('b8B8') #=> ["10000110", "01100001"]
"aaa".unpack('h2H2c') #=> ["16", "61", 97]
"\xfe\xff\xfe\xff".unpack('sS') #=> [-2, 65534]
"now=20is".unpack('M*') #=> ["now is"]
"whole".unpack('xax2aX2aX1aX2a') #=> ["h", "e", "l", "l", "o"]
=end
#【【Ruby数组】】Array
=begin
uby 数组是任何对象的有序整数索引集合。数组中的每个元素都与一个索引相关,并可通过索引进行获取。
数组的索引从 0 开始,这与 C 或 Java 中一样。一个负数的索相对于数组的末尾计数的,也就是说,索引为 -1 表示数组的最后一个元素,-2 表示数组中的倒数第二个元素,依此类推。
Ruby 数组可存储诸如 String、 Integer、 Fixnum、 Hash、 Symbol 等对象,甚至可以是其他 Array 对象。
Ruby 数组不需要指定大小,当向数组添加元素时,Ruby 数组会自动增长
=end
# 【创建数组】
# 例子
name = Array.new(20)
puts name.length #20
puts name.size #20
# 例子 可以给数组中的每个元素赋值
names = Array.new(4,'mac')
puts names
=begin
mac
mac
mac
mac
=end
puts "#{names}" #["mac", "mac", "mac", "mac"]
# 例子 new 块,填充元素
num1 = Array.new(10)
num2 = Array.new(10){|e| e = e * 2}
puts "#{num1}" #[nil, nil, nil, nil, nil, nil, nil, nil, nil, nil]
puts "#{num2}" #[0, 2, 4, 6, 8, 10, 12, 14, 16, 18]
# 数组创建方法2
num2 = Array.[](1,2,3)
# 数组创建方法3
num3 = Array[1,2,3]
puts "#{num2}" #[1, 2, 3]
puts "#{num3}" #[1, 2, 3]
# 数组创建方法4,使用范围
num4 = Array(1...4)
puts "#{num4}" #[1, 2, 3]
# 【数组的内建方法】
digits = Array(1...4)
num = digits.at(3)
puts "#{num}" #什么都没打印,不知道为什么
=begin
序号 方法 & 描述
1 array & other_array
返回一个新的数组,包含两个数组中共同的元素,没有重复。
2 array * int [or] array * str
返回一个新的数组,新数组通过连接 self 的 int 副本创建的。带有 String 参数时,相当于 self.join(str)。
3 array + other_array
返回一个新的数组,新数组通过连接两个数组产生第三个数组创建的。
4 array - other_array
返回一个新的数组,新数组是从初始数组中移除了在 other_array 中出现的项的副本。
5 str <=> other_str
把 str 与 other_str 进行比较,返回 -1(小于)、0(等于)或 1(大于)。比较是区分大小写的。
6 array | other_array
通过把 other_array 加入 array 中,移除重复项,返回一个新的数组。
7 array << obj
把给定的对象附加到数组的末尾。该表达式返回数组本身,所以几个附加可以连在一起。
8 array <=> other_array
如果数组小于、等于或大于 other_array,则返回一个整数(-1、 0 或 +1)。
9 array == other_array
如果两个数组包含相同的元素个数,且每个元素与另一个数组中相对应的元素相等(根据 Object.==),那么这两个数组相等。
10 array[index] [or] array[start, length] [or]
array[range] [or] array.slice(index) [or]
array.slice(start, length) [or] array.slice(range)
返回索引为 index 的元素,或者返回从 start 开始直至 length 个元素的子数组,或者返回 range 指定的子数组。负值索引从数组末尾开始计数(-1 是最后一个元素)。如果 index(或开始索引)超出范围,则返回 nil。
11 array[index] = obj [or]
array[start, length] = obj or an_array or nil [or]
array[range] = obj or an_array or nil
设置索引为 index 的元素,或者替换从 start 开始直至 length 个元素的子数组,或者替换 range 指定的子数组。如果索引大于数组的当前容量,那么数组会自动增长。负值索引从数组末尾开始计数。如果 length 为零则插入元素。如果在第二种或第三种形式中使用了 nil,则从 self 删除元素。
12 array.abbrev(pattern = nil)
为 self 中的字符串计算明确的缩写集合。如果传递一个模式或一个字符串,只考虑当字符串匹配模式或者以该字符串开始时的情况。
13 array.assoc(obj)
搜索一个数组,其元素也是数组,使用 obj.== 把 obj 与每个包含的数组的第一个元素进行比较。如果匹配则返回第一个包含的数组,如果未找到匹配则返回 nil。
14 array.at(index)
返回索引为 index 的元素。一个负值索引从 self 的末尾开始计数。如果索引超出范围则返回 nil。
15 array.clear
从数组中移除所有的元素。
16 array.collect { |item| block } [or]
array.map { |item| block }
为 self 中的每个元素调用一次 block。创建一个新的数组,包含 block 返回的值。
17 array.collect! { |item| block } [or]
array.map! { |item| block }
为 self 中的每个元素调用一次 block,把元素替换为 block 返回的值。
18 array.compact
返回 self 的副本,移除了所有的 nil 元素。
19 array.compact!
从数组中移除所有的 nil 元素。如果没有变化则返回 nil。
20 array.concat(other_array)
追加 other_array 中的元素到 self 中。
21 array.delete(obj) [or]
array.delete(obj) { block }
从 self 中删除等于 obj 的项。如果未找到相等项,则返回 nil。如果未找到相等项且给出了可选的代码 block,则返回 block 的结果。
22 array.delete_at(index)
删除指定的 index 处的元素,并返回该元素。如果 index 超出范围,则返回 nil。
23 array.delete_if { |item| block }
当 block 为 true 时,删除 self 的每个元素。
24 array.each { |item| block }
为 self 中的每个元素调用一次 block,传递该元素作为参数。
25 array.each_index { |index| block }
与 Array#each 相同,但是传递元素的 index,而不是传递元素本身。
26 array.empty?
如果数组本身没有包含元素,则返回 true。
27 array.eql?(other)
如果 array 和 other 是相同的对象,或者两个数组带有相同的内容,则返回 true。
28 array.fetch(index) [or]
array.fetch(index, default) [or]
array.fetch(index) { |index| block }
尝试返回位置 index 处的元素。如果 index 位于数组外部,则第一种形式会抛出 IndexError 异常,第二种形式会返回 default,第三种形式会返回调用 block 传入 index 的值。负值的 index 从数组末尾开始计数。
29 array.fill(obj) [or]
array.fill(obj, start [, length]) [or]
array.fill(obj, range) [or]
array.fill { |index| block } [or]
array.fill(start [, length] ) { |index| block } [or]
array.fill(range) { |index| block }
前面三种形式设置 self 的被选元素为 obj。以 nil 开头相当于零。nil 的长度相当于 self.length。最后三种形式用 block 的值填充数组。block 通过带有被填充的每个元素的绝对索引来传递。
30 array.first [or]
array.first(n)
返回数组的第一个元素或前 n 个元素。如果数组为空,则第一种形式返回 nil,第二种形式返回一个空的数组。
31 array.flatten
返回一个新的数组,新数组是一个一维的扁平化的数组(递归)。
32 array.flatten!
把 array 进行扁平化。如果没有变化则返回 nil。(数组不包含子数组。)
33 array.frozen?
如果 array 被冻结(或排序时暂时冻结),则返回 true。
34 array.hash
计算数组的哈希代码。两个具有相同内容的数组将具有相同的哈希代码。
35 array.include?(obj)
如果 self 中包含 obj,则返回 true,否则返回 false。
36 array.index(obj)
返回 self 中第一个等于 obj 的对象的 index。如果未找到匹配则返回 nil。
37 array.indexes(i1, i2, ... iN) [or]
array.indices(i1, i2, ... iN)
该方法在 Ruby 的最新版本中被废弃,所以请使用 Array#values_at。
38 array.indices(i1, i2, ... iN) [or]
array.indexes(i1, i2, ... iN)
该方法在 Ruby 的最新版本中被废弃,所以请使用 Array#values_at。
39 array.insert(index, obj...)
在给定的 index 的元素前插入给定的值,index 可以是负值。
40 array.inspect
创建一个数组的可打印版本。
41 array.join(sep=$,)
返回一个字符串,通过把数组的每个元素转换为字符串,并使用 sep 分隔进行创建的。
42 array.last [or] array.last(n)
返回 self 的最后一个元素。如果数组为空,则第一种形式返回 nil。
43 array.length
返回 self 中元素的个数。可能为零。
44 array.map { |item| block } [or]
array.collect { |item| block }
为 self 的每个元素调用一次 block。创建一个新的数组,包含 block 返回的值。
45 array.map! { |item| block } [or]
array.collect! { |item| block }
为 array 的每个元素调用一次 block,把元素替换为 block 返回的值。
46 array.nitems
返回 self 中 non-nil 元素的个数。可能为零。
47 array.pack(aTemplateString)
根据 aTemplateString 中的指令,把数组的内容压缩为二进制序列。指令 A、 a 和 Z 后可以跟一个表示结果字段宽度的数字。剩余的指令也可以带有一个表示要转换的数组元素个数的数字。如果数字是一个星号(*),则所有剩余的数组元素都将被转换。任何指令后都可以跟一个下划线(_),表示指定类型使用底层平台的本地尺寸大小,否则使用独立于平台的一致的尺寸大小。在模板字符串中空格会被忽略。
48 array.pop
从 array 中移除最后一个元素,并返回该元素。如果 array 为空则返回 nil。
49 array.push(obj, ...)
把给定的 obj 附加到数组的末尾。该表达式返回数组本身,所以几个附加可以连在一起。
50 array.rassoc(key)
搜索一个数组,其元素也是数组,使用 == 把 key 与每个包含的数组的第二个元素进行比较。如果匹配则返回第一个包含的数组。
51 array.reject { |item| block }
返回一个新的数组,包含当 block 不为 true 时的数组项。
52 array.reject! { |item| block }
当 block 为真时,从 array 删除元素,如果没有变化则返回 nil。相当于 Array#delete_if。
53 array.replace(other_array)
把 array 的内容替换为 other_array 的内容,必要的时候进行截断或扩充。
54 array.reverse
返回一个新的数组,包含倒序排列的数组元素。
55 array.reverse!
把 array 进行逆转。
56 array.reverse_each {|item| block }
与 Array#each 相同,但是把 array 进行逆转。
57 array.rindex(obj)
返回 array 中最后一个等于 obj 的对象的索引。如果未找到匹配,则返回 nil。
58 array.select {|item| block }
调用从数组传入连续元素的 block,返回一个数组,包含 block 返回 true 值时的元素。
59 array.shift
返回 self 的第一个元素,并移除该元素(把所有的其他元素下移一位)。如果数组为空,则返回 nil。
60 array.size
返回 array 的长度(元素的个数)。length 的别名。
61 array.slice(index) [or] array.slice(start, length) [or]
array.slice(range) [or] array[index] [or]
array[start, length] [or] array[range]
返回索引为 index 的元素,或者返回从 start 开始直至 length 个元素的子数组,或者返回 range 指定的子数组。负值索引从数组末尾开始计数(-1 是最后一个元素)。如果 index(或开始索引)超出范围,则返回 nil。
62 array.slice!(index) [or] array.slice!(start, length) [or]
array.slice!(range)
删除 index(长度是可选的)或 range 指定的元素。返回被删除的对象、子数组,如果 index 超出范围,则返回 nil。
63 array.sort [or] array.sort { | a,b | block }
返回一个排序的数组。
64 array.sort! [or] array.sort! { | a,b | block }
把数组进行排序。
65 array.to_a
返回 self。如果在 Array 的子类上调用,则把接收参数转换为一个 Array 对象。
66 array.to_ary
返回 self。
67 array.to_s
返回 self.join。
68 array.transpose
假设 self 是数组的数组,且置换行和列。
69 array.uniq
返回一个新的数组,移除了 array 中的重复值。
70 array.uniq!
从 self 中移除重复元素。如果没有变化(也就是说,未找到重复),则返回 nil。
71 array.unshift(obj, ...)
把对象前置在数组的前面,其他元素上移一位。
72 array.values_at(selector,...)
返回一个数组,包含 self 中与给定的 selector(一个或多个)相对应的元素。选择器可以是整数索引或者范围。
73 array.zip(arg, ...) [or]
array.zip(arg, ...){ | arr | block }
把任何参数转换为数组,然后把 array 的元素与每个参数中相对应的元素合并。
数组 pack 指令
下表列出了方法 Array#pack 的压缩指令。
指令 描述
@ 移动到绝对位置。
A ASCII 字符串(填充 space,count 是宽度)。
a ASCII 字符串(填充 null,count 是宽度)。
B 位字符串(降序)
b 位字符串(升序)。
C 无符号字符。
c 字符。
D, d 双精度浮点数,原生格式。
E 双精度浮点数,little-endian 字节顺序。
e 单精度浮点数,little-endian 字节顺序。
F, f 单精度浮点数,原生格式。
G 双精度浮点数,network(big-endian)字节顺序。
g 单精度浮点数,network(big-endian)字节顺序。
H 十六进制字符串(高位优先)。
h 十六进制字符串(低位优先)。
I 无符号整数。
i 整数。
L 无符号 long。
l Long。
M 引用可打印的,MIME 编码。
m Base64 编码字符串。
N Long,network(big-endian)字节顺序。
n Short,network(big-endian)字节顺序。
P 指向一个结构(固定长度的字符串)。
p 指向一个空结束字符串。
Q, q 64 位数字。
S 无符号 short。
s Short。
U UTF-8。
u UU 编码字符串。
V Long,little-endian 字节顺序。
v Short,little-endian 字节顺序。
w BER 压缩的整数 \fnm。
X 向后跳过一个字节。
x Null 字节。
Z 与 a 相同,除了 null 会被加上 *。
实例
尝试下面的实例,压缩各种数据。
实例
a = [ "a", "b", "c" ]
n = [ 65, 66, 67 ]
puts a.pack("A3A3A3") #=> "a b c "
puts a.pack("a3a3a3") #=> "a\000\000b\000\000c\000\000"
puts n.pack("ccc") #=> "ABC"
以上实例运行输出结果为:
a b c
abc
ABC
=end
# 【【哈希】】 Hash
=begin
健值对集合。类似于数组,不过索引不局限于数字。
索引几乎可以是任何对象
和数组有一个很重要的区别,无序的,如果顺序很重要,就使用数组了。
=end
#创建哈希
month1 = Hash.new
puts "#{month1}" #{}
puts month1[0] #空
puts month1[72] #空
month2 = Hash.new("months")
puts "#{month2}" #{}
puts month2[0] #months
puts month2[72] #months
month3 = Hash.new"months"
puts "#{month3}" #{}
puts month3[0] #months
puts month3[72] #months
# 例子
H = Hash['a' => 100,'b' => 200]
puts H['a'] #100
puts H['b'] #200
# 【备注】可使用任意Ruby对象作为键或值,甚至可以使用数组
#[1,'jan'] => 'January'
# 例子
months = Hash.new("months")
months = {'1' => 'January','2' => 'Febrary',[1,'jan'] => 'January'}
keys = months.keys
puts "#{keys}" #["1", "2", [1, "jan"]]
#【【Ruby日期、时间】】Date Time
# 例子 获取当前日期和时间
time1 = Time.new
puts "当前时间:#{time1}"
print "当前时间:" , time1.inspect, "\n"
time2 = Time.now
puts "当前时间:#{time2}"
print "当前时间:", time2.inspect
=begin
当前时间:2018-07-07 12:42:17 +0800
当前时间:2018-07-07 12:42:17 +0800
当前时间:2018-07-07 12:42:17 +0800
当前时间:2018-07-07 12:42:17 +0800
=end
# 【获取Date & Time 组件】
time = Time.new
puts "当前时间:" ,time
puts time.year #2018
puts time.month #7
puts time.day #7【一个月中的第几天】
puts time.wday #6【一周中的星期几】
puts time.yday #188【一年中的第几天】
puts time.hour #12
puts time.min #46
puts time.sec #20
puts time.usec #840399【微秒】
puts time.zone #CST 【备注】可以表示四个国家的标准时间,四个不同的时区,根据当前编程环境自行判断的结果
# 【Time.utc Time.gm Time.local 函数】格式化
puts Time.local(2018,7,7) #2018-07-07 00:00:00 +0800
puts Time.local(2018,7,7,13,29) #2018-07-07 13:29:00 +0800
puts Time.utc(2018,7,7,13,29) #2018-07-07 13:29:00 UTC
puts Time.gm(2018,7,7,13,28) #2018-07-07 13:28:00 UTC 【备注】格林威治时间,通UTC
# 时间组件组成的数组
time = Time.new
values = time.to_a
puts "#{values}" #[32, 35, 13, 7, 7, 2018, 6, 188, false, "CST"] 【备注】[sec,min,hour,day,month,year,wday,yday,isdst,zone]
# 该数组可被传到Time.utc Time.local 来获取日期的不同格式
time = Time.now
values = time.to_a
puts Time.utc(*values) #2018-07-07 13:38:38 UTC
# 【获取时间的方式,从纪元以来的秒数(平台相关)】
time = Time.now.to_i #纪元以来的秒数
puts time
time_obj = Time.at(time) #把秒数转成Time对象
puts time_obj
time_f = Time.now.to_f #返回纪元以来的秒数,包含微秒
puts time_f
=begin
1530942192
2018-07-07 13:43:12 +0800
1530942192.656307
=end
# 【时区和夏令时】
time = Time.now
puts time.zone #CST
puts time.utc_offset #28800 【相对于utc的多少秒偏移】
puts time.zone #CST
puts time.isdst #false 【如果utc没有夏令时】
puts time.utc? #false 【如果在utc时区】
puts time.localtime #2018-07-07 13:57:50 +0800
time.gmtime #【转换为UTC】
puts time.getlocal #2018-07-07 13:57:50 +0800 【备注】返回本地时区中一个新的Time对象
puts time.getutc #2018-07-07 06:03:31 UTC 【备注】返回utc中一个新的Time对象
puts time #2018-07-07 05:59:47 UTC
puts time.zone
puts time.utc_offset
puts time.isdst
puts time.utc?
time.localtime # 转换回本地时间
puts time.getlocal
puts time.getutc
=begin
CST
28800
CST
false
false
2018-07-07 14:05:03 +0800
2018-07-07 14:05:03 +0800
2018-07-07 06:05:03 UTC
2018-07-07 06:05:03 UTC
UTC
0
false
true
2018-07-07 14:05:03 +0800
2018-07-07 06:05:03 UTC
=end
# 【格式化时间和日期】
time = Time.now
puts time.to_s
puts time.ctime
puts time.localtime
puts time.strftime('%Y-%m-%d %H:%M:%S')
=begin
Sat Jul 7 14:09:16 2018
2018-07-07 14:09:16 +0800
2018-07-07 14:09:16
=end
=begin
时间格式化指令
下表所列出的指令与方法 Time.strftime 一起使用。
指令 描述
%a 星期几名称的缩写(比如 Sun)。
%A 星期几名称的全称(比如 Sunday)。
%b 月份名称的缩写(比如 Jan)。
%B 月份名称的全称(比如 January)。
%c 优选的本地日期和时间表示法。
%d 一个月中的第几天(01 到 31)。
%H 一天中的第几小时,24 小时制(00 到 23)。
%I 一天中的第几小时,12 小时制(01 到 12)。
%j 一年中的第几天(001 到 366)。
%m 一年中的第几月(01 到 12)。
%M 小时中的第几分钟(00 到 59)。
%p 子午线指示(AM 或 PM)。
%S 分钟中的第几秒(00 或 60)。
%U 当前年中的周数,从第一个星期日(作为第一周的第一天)开始(00 到 53)。
%W 当前年中的周数,从第一个星期一(作为第一周的第一天)开始(00 到 53)。
%w 一星期中的第几天(Sunday 是 0,0 到 6)。
%x 只有日期没有时间的优先表示法。
%X 只有时间没有日期的优先表示法。
%y 不带世纪的年份表示(00 到 99)。
%Y 带有世纪的年份。
%Z 时区名称。
%% % 字符。
=end
# 【时间算法】
now = Time.now
puts now
past = now - 10
puts past
future = now + 10
puts future
diff = future - now
puts diff
=begin
2018-07-07 14:14:17 +0800
2018-07-07 14:14:07 +0800
2018-07-07 14:14:27 +0800
10.0
=end
# 【【Ruby 范围】】
=begin
1. 作为序列的范围
2。作为条件的范围
3。作为间隔的范围
=end
# 【作为序列的范围】
$, = "," # Array 值分隔符
range1 = (1..10)
puts "#{range1}" #1..10
puts range1 #1..10
range1_1 = range1.to_a
puts "#{range1_1}" #[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
range2 = ('bar'..'bat').to_a
puts "#{range2}" #["bar", "bas", "bat"]
# 例子 遍历
digits = 0..9
puts digits.include?(5)
ret = digits.min
puts "最小值:#{ret}"
ret = digits.max
puts "最大值:#{ret}"
ret = digits.reject {|i| i < 5}
puts "不符合条件的是:#{ret}"
digits.each do |digit|
puts "在循环中: #{digit}"
end
=begin
最小值:0
最大值:9
不符合条件的是:[5, 6, 7, 8, 9]
在循环中: 0
在循环中: 1
在循环中: 2
在循环中: 3
在循环中: 4
在循环中: 5
在循环中: 6
在循环中: 7
在循环中: 8
在循环中: 9
=end
#【作为条件的范围】
score = 70
result = case score
when 0..40
"糟糕的分数"
when 41..60
"快要及格"
when 61..70
"及格分数"
when 71..100
"良好分数"
else
"错误的分数"
end
puts result #及格分数
#【作为间隔的判断】
if ((1..5) === 5)
puts "5 在 (1..5) 里"
end
if (('a'..'j') === 'c')
puts "c 在 ('a'..'j') 里"
end
if (('a'..'j') === 'z')
puts "z 在 ('a'..'j') 里"
end
=begin
5 在 (1..5) 里
c 在 ('a'..'j') 里
=end
#【【迭代器】】each collect
# 迭代器是集合支持的方法。在Ruby中,数组和哈希可以称之为集合。迭代器返回集合的所有元素。
# 【each】
ary = [1,2,3,4,5]
ary.each do |i|
puts i
end
print "****************\n"
puts ary
=begin
1
2
3
4
5
****************
1
2
3
4
5
=end
# 【collect】
a = [1,2,3]
b = a.collect{|x|x}
puts b
=begin
1
2
3
=end
#例子
a = [1,2,3]
b = a.collect{|x| 10 * x}
puts "#{b}" #[10, 20, 30]
#【【文件的输入与输出】】
=begin
Ruby提供了一整套I/O相关的方法,在内核(Kernel)模块中实现。所有的I/O方法派生自I/O类。
=end
# 【gets】
=begin
puts 'enter a value:'
value = gets
puts value
=end
#【putc】puts输出整个字符串到屏幕上。putc一次输出一个字符。
str = 'Hello Ruby!'
putc str #H
putc "\n"
#【打开和关闭文件】
=begin
模式 描述
r 只读模式。文件指针被放置在文件的开头。这是默认模式。
r+ 读写模式。文件指针被放置在文件的开头。新写入的覆盖原有的。
w 只写模式。如果文件存在,则重写文件。如果文件不存在,则创建一个新文件用于写入。
w+ 读写模式。如果文件存在,则重写已存在的文件。如果文件不存在,则创建一个新文件用于读写。
a 只写模式。如果文件存在,则文件指针被放置在文件的末尾。也就是说,文件是追加模式。如果文件不存在,则创建一个新文件用于写入。
a+ 读写模式。如果文件存在,则文件指针被放置在文件的末尾。也就是说,文件是追加模式。如果文件不存在,则创建一个新文件用于读写。
=end
aFile = File.new('input.txt','r') # input.txt 内容
if aFile
content = aFile.sysread(20)
puts content
else
puts 'unable to open file!'
end
#This is a sample tex 【备注】输入文件的头20个字符,文件指针将被放置在文件中第21个字符的位置。
# 【syswrite方法】
aFile = File.new('input.txt','r+')
if aFile
aFile.syswrite('ABCDEFG')
else
puts 'unable to open file!'
end
# 现在文件内容 ABCDEFG a sample text file for testing perpose.
# 【each_byte】
# 当前文件内容 this is a sample text file for testing perpose.
aFile = File.new('input.txt','r+')
if aFile
aFile.syswrite('ABCDEF')
aFile.rewind
#aFile.each_byte {|ch| putc ch;putc ?.} #【备注】这一句与下面一句是等价的
aFile.each_byte {|ch| putc ch;putc '.'}
else
puts 'unable to open file!'
end
=begin
文件内容:ABCDEFG a sample text file for testing perpose.
控制台打印:
A.B.C.D.E.F.G. .a. .s.a.m.p.l.e. .t.e.x.t. .f.i.l.e. .f.o.r. .t.e.s.t.i.n.g. .p.e.r.p.o.s.e...
.
=end
# 练习
putc "\n"
putc 'a';
putc ?.
putc '.'
putc "\n"
=begin
a..
=end
#【IO readlines方法】逐行返回
=begin
此时文件的内容:
ABCDEFG a sample text file for testing perpose.
这是第二行。
=end
arr = IO.readlines('input.txt')
puts arr[0]
puts arr[1]
=begin
ABCDEFG a sample text file for testing perpose.
这是第二行。
=end
# 【IO foreach方法】与IO.readlines方法不同的是,IO.foreach方法与块关联
# #例子 将把文件 test 的内容逐行传给变量 block,然后输出将显示在屏幕上
# =begin
# 此时文件的内容:
# ABCDEFG a sample text file for testing perpose.
# 这是第二行。
# =end
IO.foreach('input.txt'){|block| puts block}
=begin
ABCDEFG a sample text file for testing perpose.
这是第二行。
=end
#【重命名和删除文件】 rename delete
File.rename('input.txt','input.txt')
#此时看到已经变名字了
File.rename('input.txt','input.txt')
#此时看到名字已经改回来了
# 【文件查询】
# 打开文件前,检查文件是否已存在
File.open('a.txt') if File::exists?('a.txt')
# 查询文件是否是一个文件
puts File.file?('input.txt') #true
# 检查给定的文件名是否是一个目录
puts File::directory?('/usr/local/bin') #true
puts File::directory?('input.txt') #false
# 检查文件是否可读、可写、可执行
puts File.readable?('input.txt') #true
puts File.writable?('input.txt') #true
puts File.executable?('input.txt') #false
# 检查文件大小是否为0
puts File.zero?('input.txt') #false
# 返回文件大小
puts File.size?('input.txt') #67
# 检查文件的类型
puts File.ftype('input.txt') #file
=begin
ftype 方法通过返回下列中的某个值来标识了文件的类型:file、 directory、 characterSpecial、 blockSpecial、 fifo、 link、 socket 或 unknown。
=end
# 文件被创建、修改、最后访问的时间
puts File::ctime('input.txt')
puts File::mtime('input.txt')
puts File::atime('input.txt')
# 【【Ruby中的目录】】所有文件都包含在目录中。File 处理文件。Dir 处理目录。
# 查看当前目录
puts Dir.pwd #/Users/suren/RubymineProjects/ruby_test_one
# 获取指定目录内的文件和目录列表
puts Dir.entries('/Users/suren/RubymineProjects/ruby_test_one')
=begin
返回一个数组
.
..
.idea
arith.rb
class_and_obj.rb
data.rb
grammer.rb
input.txt
moral.rb
support.rb
test_one.rb
trip.rb
x.rb
=end
puts Dir.entries('/Users/suren/RubymineProjects/ruby_test_one').join(' ')
#. .. .idea arith.rb class_and_obj.rb data.rb grammer.rb input.txt moral.rb support.rb test_one.rb trip.rb x.rb
# Dir.foreach返回一个数组,包含指定目录内的所有项,同Dir.entries
Dir.foreach('/Users/suren/RubymineProjects/ruby_test_one') do |entry|
puts entry
end
=begin
.
..
.idea
arith.rb
class_and_obj.rb
data.rb
grammer.rb
input.txt
moral.rb
support.rb
test_one.rb
trip.rb
x.rb
=end
# 创建目录
#Dir.mkdir('aa',755) # 还可以顺便设置文件的权限
# 创建文件 & 临时目录
=begin
临时文件是那些在程序执行过程中被简单地创建,但不会永久性存储的信息。
Dir.tmpdir 提供了当前系统上临时目录的路径,但是该方法默认情况下是不可用的。可以把Dir.tmpdir 和 File.join 一起用,创建一个独立于平台的独立文件
=end
# 例子
require 'tmpdir'
tempfilename = File.join(Dir.tmpdir,'tingtong')
puts tempfilename # 本次执行结果: /var/folders/7b/v65b2_394_jdz_24k80htg840000gn/T/tingtong
tempfile = File.new(tempfilename,'w')
tempfile.puts "This is a temporary file"
tempfile.rewind
tempfile_for_read = File.new(tempfilename,'r')
value = tempfile_for_read.sysread(30)
puts value
tempfile.close
tempfile_for_read.close
File.delete(tempfilename)
=begin
/var/folders/7b/v65b2_394_jdz_24k80htg840000gn/T/tingtong
This is a temporary file
=end
#例子 Ruby的标准库包含了Tempfile,可用于创建临时文件
require 'tempfile'
f = Tempfile.new('tingtong4')
f.puts "Hello Ruby!"
puts f.path # 当前执行结果:/var/folders/7b/v65b2_394_jdz_24k80htg840000gn/T/tingtong420180707-60134-1g73o9p
f.close
# 【【Ruby异常】】
=begin
从 begin 到 rescue 中的一切是受保护的。如果代码块执行期间发生了异常,控制会传到 rescue 和 end 之间的块。
对于 begin 块中的每个 rescue 子句,Ruby 把抛出的异常与每个参数进行轮流比较。如果 rescue 子句中命名的异常与当前抛出的异常类型相同,或者是该异常的父类,则匹配成功。
如果异常不匹配所有指定的错误类型,我们可以在所有的 rescue 子句后使用一个 else 子句
=end
# 例子
begin
file = open("/unexistant_file")
if file
puts "File opened successfully"
end
rescue
file = STDIN
end
#puts "#{file}==#{STDIN}\n" ##<IO:0x007f9c6409c718>==#<IO:0x007f9c6409c718>
begin #开始
#试图打开一个不存在的文件,注意,其实直接调用open也可以!Ruby实在太乱了!不过 open 返回的是File对象而不是文件内容
file = open('/cygdrive/d/workspace/notexists')
if file
puts "文件打开正常,path=#{file.path}"
end
rescue Errno::ENOENT => e #文件打不开的具体异常类型是这种,很奇怪把!
#STDIN 是标准输入,此处意思是如果拿不到File对象就用标准输入对象代替,并没有什么特别的用意
file = STDIN
puts "这是一种Errno::ENOENT"
puts
#用 e.inspect可以看到具体的异常类型
puts "e.inspect #{e.inspect}"
puts
# 用 e.message 可以打印出信息
puts "e.message: #{e.message}"
puts
#用 e.backtrace.inspect 可以打印出堆栈
puts "e.backtrace.inspect: #{e.backtrace.inspect}"
puts
puts "异常信息: #{$!}"
puts
puts "异常代码位置: #{$@}"
rescue StandardError => e #获取e对象
#STDIN 是标准输入,此处意思是如果拿不到File对象就用标准输入对象代替,并没有什么特别的用意
file = STDIN
puts "这是一种StandardError" #默认都是StandardError
rescue => e #还可以直接不写类型,意思是所有类型,相当于else了
#STDIN 是标准输入,此处意思是如果拿不到File对象就用标准输入对象代替,并没有什么特别的用意
file = STDIN
puts "不知道是什么类型的Error"
ensure
puts "怎样都会进入的代码"
end #结束
#逗号隔开并不是连在一起输出,而是多次调用print方法的意思
print file, " == ", STDIN
=begin
这是一种Errno::ENOENT
e.inspect #<Errno::ENOENT: No such file or directory @ rb_sysopen - /cygdrive/d/workspace/notexists>
e.message: No such file or directory @ rb_sysopen - /cygdrive/d/workspace/notexists
e.backtrace.inspect: ["/Users/suren/RubymineProjects/ruby_test_one/test_one.rb:3:in `initialize'", "/Users/suren/RubymineProjects/ruby_test_one/test_one.rb:3:in `open'", "/Users/suren/RubymineProjects/ruby_test_one/test_one.rb:3:in `<top (required)>'", "-e:1:in `load'", "-e:1:in `<main>'"]
异常信息: No such file or directory @ rb_sysopen - /cygdrive/d/workspace/notexists
异常代码位置: ["/Users/suren/RubymineProjects/ruby_test_one/test_one.rb:3:in `initialize'", "/Users/suren/RubymineProjects/ruby_test_one/test_one.rb:3:in `open'", "/Users/suren/RubymineProjects/ruby_test_one/test_one.rb:3:in `<top (required)>'", "-e:1:in `load'", "-e:1:in `<main>'"]
怎样都会进入的代码
#<IO:0x007fcbe909c718> == #<IO:0x007fcbe909c718>
=end
# 【retry】
begin
file = open('/unexistant_file')
if file
puts "File opened successfully"
end
rescue
filename = open('input.txt')
retry
end
puts filename
# 【retry】
#例子 死循环了
=begin
begin
file = open('/unexistant_file')
if file
puts "File opened successfully"
end
rescue
filename = open('/input.txt')
retry
end
puts filename
=end
# 例子 针对上面例子的解决方案
aa = 'input1.txt'
begin
file = open($aa)
if file
puts 'file opened successfully'
end
rescue
$aa = 'input.txt'
retry
end
puts file
=begin
以下是处理流程:
打开时发生异常。
跳到 rescue。fname 被重新赋值。
通过 retry 跳到 begin 的开头。
这次文件成功打开。
继续基本的过程。
注意:如果被重新命名的文件不存在,本实例代码会无限尝试。所以异常处理时,谨慎使用 retry。
【备注】我这里并未打印出任何内容
=end
# 【raise】
=begin
语法
raise
或
raise "Error Message"
或
raise ExceptionType, "Error Message"
或
raise ExceptionType, "Error Message" condition
第一种形式简单地重新抛出当前异常(如果没有当前异常则抛出一个 RuntimeError)。这用在传入异常之前需要解释异常的异常处理程序中。
第二种形式创建一个新的 RuntimeError 异常,设置它的消息为给定的字符串。该异常之后抛出到调用堆栈。
第三种形式使用第一个参数创建一个异常,然后设置相关的消息为第二个参数。
第四种形式与第三种形式类似,您可以添加任何额外的条件语句(比如 unless)来抛出异常。
=end
# 例子
begin
puts 'I am before the raise'
raise 'An error has occurred.'
puts 'I am after the raise'
rescue
puts 'I am rescued.'
end
puts 'I am after the begin block'
=begin
I am before the raise
I am rescued.
I am after the begin block
=end
#例子
begin
raise 'A test Exception.'
rescue Exception => e
puts e.message
puts e.backtrace.inspect
end
=begin
A test Exception.
["/Users/suren/RubymineProjects/ruby_test_one/test_one.rb:70:in `<top (required)>'", "-e:1:in `load'", "-e:1:in `<main>'"]
=end
# 【ensure】相当于finally
begin
raise 'A Test Exception'
rescue Exception => e
puts e.message
puts e.backtrace.inspect
ensure
puts 'Ensuring execution'
end
=begin
A Test Exception
["/Users/suren/RubymineProjects/ruby_test_one/test_one.rb:83:in `<top (required)>'", "-e:1:in `load'", "-e:1:in `<main>'"]
Ensuring execution
=end
# 【else】只有在代码主体未抛出异常时执行
# 例子
begin
puts "I'm not raising exeception."
rescue Exception => e
puts e.message
puts e.backtrace.inspect
else
puts "Congratuations-- no errors!"
ensure
puts 'Ensuring execution'
end
=begin
I'm not raising exeception.
Congratuations-- no errors!
Ensuring execution
=end
#throw/cathc
#例子
#例子
"""
def promptAndGet(prompt)
print prompt
res = readline.chomp
throw :quitRequested if res == '!'
return res
end
catch :quitReques do
## 首先进入catch块中,这是第一句被执行的,进入quitRequested方法,如果不输入感叹号,就不throw,直接返回调用处,这一行返回结果给name变量。然后接着执行catch中的下一行,直到readline.chmop接收到一个感叹号,此时会抛出异常,catch不会接,只会终止。
name = promptAndGet('Name:')
age = promptAndGet('age:')
sex = promptAndGet('sex:')
end
promptAndGet('Name11:')
"""
'''
Name:wxue
age:er
sex:femail
Name11:wxue
'''
#例子
"""
def promptAndGet(prompt)
print prompt
res = readline.chomp
throw :quitRequested if res == '!'
return res
end
catch :quitReques do
name = promptAndGet('Name:')
age = promptAndGet('age:')
sex = promptAndGet('sex:')
end
promptAndGet('Name11:')
"""
"""
Name:wxue
age:23
sex:femail
Name11:!
/Users/suren/RubymineProjects/ruby_test_one/x.rb:31:in `throw': uncaught throw :quitRequested (UncaughtThrowError)
from /Users/suren/RubymineProjects/ruby_test_one/x.rb:31:in `promptAndGet'
from /Users/suren/RubymineProjects/ruby_test_one/x.rb:41:in `<top (required)>'
from -e:1:in `load'
from -e:1:in `<main>'
"""
#例子
"""
def promptAndGet(prompt)
print prompt
res = readline.chomp
throw :quitRequested if res == '!'
return res
end
catch :quitRequested do
name = promptAndGet('Name:')
age = promptAndGet('age:')
sex = promptAndGet('sex:')
end
promptAndGet('Name11:')
"""
"""
Name:wxue
age:23
sex:femail
Name11:!
/Users/suren/RubymineProjects/ruby_test_one/x.rb:85:in `throw': uncaught throw :quitRequested (UncaughtThrowError)
from /Users/suren/RubymineProjects/ruby_test_one/x.rb:85:in `promptAndGet'
from /Users/suren/RubymineProjects/ruby_test_one/x.rb:94:in `<top (required)>'
from -e:1:in `load'
from -e:1:in `<main>'
"""
#例子
"""
def promptAndGet(prompt)
print prompt
res = readline.chomp
throw :quitRequested if res == '!'
return res
end
catch :quitRequested do
name = promptAndGet('Name:')
age = promptAndGet('age:')
sex = promptAndGet('sex:')
end
promptAndGet('Name11:')
"""
'''
Name:wxue
age:er
sex:femail
Name11:wxue
'''
#【备注】Ruby和其他语言不太一样,这里throw。。catch,不是主要处理异常的,而可以理解成控制流程的。
# 【类Exception】
=begin
Ruby 的标准类和模块抛出异常。所有的异常类组成一个层次,包括顶部的 Exception 类在内。下一层是七种不同的类型:
Interrupt
NoMemoryError
SignalException
ScriptError
StandardError
SystemExit
Fatal 是该层中另一种异常,但是 Ruby 解释器只在内部使用它。
ScriptError 和 StandardError 都有一些子类,但是在这里我们不需要了解这些细节。最重要的事情是创建我们自己的异常类,它们必须是类 Exception 或其子代的子类
=end
#例子
=begin
class FileSaveError < StandardError
attr_reader :reason
def initialize(reason)
@reason = reason
end
end
File.open('inpu.txt', "w") do |file|
begin
# 写出数据 ...
rescue
# 发生错误
raise FileSaveError.new($!)
end
end
a = FileSaveError.new('abc')
p a.reason #abc
=end
# 【Ruby】【Symbol】
p :foo.object_id
p :foo.object_id
p :"foo".object_id
p :'foo'.object_id
p "foo".object_id
p "foo".object_id
p 'foo'.object_id
p 'foo'.object_id
=begin
2002
2002
2002
2002
2004
2006
2008
2010
=end
# 【:: 和 :】
# :: 是 引用或调用各种对象(Ruby中一切皆对象): 是symbol
# ::例子 【如果 Foo::小写(new,test)---->就去需找方法 如果 Foo::大写(A,VERSION)--->就去寻找常量】
class Mao
PPP='aaaaa'
def ppp
puts "maohaofu"
end
end
def maomao
puts ::Mao.new::ppp
puts ::Mao:: new::ppp # 和上一行一样效果
puts ::Mao::PPP
end
maomao()
=begin
这样会不会明白些
输出
maohaofu
maohaofu
aaaaa
=end
# : 例子
=begin
Symbol 是什么
Ruby 是一个强大的面向对象脚本语言(本文所用 Ruby 版本为1.8.6),在 Ruby 中 Symbol 表示“名字”,比如字符串的名字,标识符的名字。
创建一个 Symbol 对象的方法是在名字或者字符串前面加上冒号:
创建 symbol 对象
:foo
:test
:”abc”
:”I am a boy”
你可能会问,字符串就是字符串,干吗还有字符串的名字?这是因为在 Ruby 中字符串也是一种对象,即 String 对象。无论其结构还是操作和 Symbol 对象都是不同的。
在 Ruby 中每一个对象都有唯一的对象标识符(Object Identifier),可以通过 object_id 方法来得到一个对象的标识符。我们来看看 Symbol 对象和 String 对象的差别:
Ruby 对象标识符
irb(main):001:0> puts :foo.object_id
327458
=> nil
irb(main):002:0> puts :foo.object_id
327458
=> nil
irb(main):003:0> puts :"foo".object_id
327458
=> nil
irb(main):004:0> puts "foo".object_id
24303850
=> nil
irb(main):005:0> puts "foo".object_id
24300010
=> nil
irb(main):006:0> puts "foo".object_id
24296170
=> nil
可以看到,前三行语句中的 :foo (或者 :"foo")都是同一个 Symbol 对象,其 object id 为327458,而后三行中的字符串”foo”都是不同的对象,其 object id 依次为24303850、24300010、24296170。
可见,每个 String 对象都是不同的,即便他们包含了相同的字符串内容;而对于 Symbol 对象,一个名字(字符串内容)唯一确定一个 Symbol 对象。
值得注意的是创建 Symbol 对象的字符串中不能含有’\0’字符,而 String 对象是可以的。
非法 Symbol 字符串
irb(main):001:0> :"fo\0o"
SyntaxError: compile error
(irb):1: symbol cannot contain '\0'
from (irb):1
irb(main):002:0> :"foo\0"
SyntaxError: compile error
(irb):2: symbol cannot contain '\0'
from (irb):2
irb(main):003:0> puts "foo\0".object_id
24305140
=> nil
irb(main):004:0> puts "fo\0o".object_id
24301000
=> nil
irb(main):005:0>
除了可以采用一般的字符串,还可以使用操作符(例如+, -, *, /),变量,常量,方法甚至类的名字来创建Symbol 对象,例如:+就是一个合法的 Symbol 。实际上,在 Ruby 内部操作符、变量等名字本身就是作为Symbol 处理的,例如当你定义一个实例变量时, Ruby 会自动创建一个 Symbol 对象,例如 @test 对应为 :@test 。
实例变量的 Symbol
class Test
attr_accessor :test
end
这个类定义了一个具有读写方法的实例变量 @test 。实际上 Ruby 创建了两个 Symbol ,一个是实例变量的symbol :@test ,另一个是 :test 。那如果使用字符串对象 ”test” 作为参数呢?也可以,仍然会创建两个 symbol,:test 和 :@test ,为什么还会创建 :test 呢?这是和Ruby的实现相关的(至少Ruby1.8.6里是这样)。
注意,类变量 @@test 和实例变量 @test 对应的 Symbol 显然是不同的。记住:名字相同,则Symbol 相同。
名字相同, Symbol 相同
class Test
puts :Test.object_id
Test = 10
puts :Test.object_id
def Test
puts :Test.object_id
end
end
Test.new.Test
运行结果
224298
224298
224298
名字不同, Symbol 不同
class Test
puts :Test.object_id
@@test = 10
puts :@@test.object_id
def test
puts :test.object_id
@test = 10
puts :@test.object_id
end
end
t =Test.new
t.test
运行结果
224298
288068
79858
288108
第一个例子里,类名、常量名和方法名都是 Test ,因此相应的 Symbol 对象都是 :Test 。不用担心, Ruby 可以很好区分它在不同上下文中到底表示什么。当然这并不是一个好的编程风格,但对于理解 Ruby 的 Symbol还是有帮助的: Symbol 表示一个名字,仅此而已。
Symbol 对象一旦定义将一直存在,直到程序执行退出。所有 Symbol 对象存放在 Ruby 内部的符号表中,可以通过类方法Symbol.all_symbols 得到当前 Ruby 程序中定义的所有 Symbol 对象,该方法返回一个 Symbol 对象数组。由于 Symbol 比较多,你可以 dump 到文件中来查看。
all_symbols 方法
irb(main):001:0> Symbol.all_symbols.size
=> 4047
irb(main):002:0> Symbol.all_symbols[0..9]
=> [:@level_notifier, :ppx, :msg_dn, :version, :secs, :@user, :pos, :socketpair,
:TkENSURE, :HTTPAccepted]
irb(main):003:0> File.open("sym", "w") do |file| file.puts Symbol.all_symbols end
=> nil
Symbol 和 String
Symbol 对象和 String 对象是完全不同的东西,对象标识符很明确的说明了这一点。除此之外,我们还可以从两种对象的方法上区分。
查看 Ruby 库参考,你会发现 String 类有非常多的方法,包括 Mixed-in 方法(Ruby中一个类通过 include 其他模块而得到的方法,实现多重继承的效果)、类方法和实例方法;而 Symbol 类只有一个类方法 all_symbols 和7个实例方法。
例如,可以通过 []= 方法改变 string 的内容,而 symbol 则不行:
[]= 方法比较
irb(main):001:0> s="test"
=> "test"
irb(main):002:0> s[0]='1'
=> "1"
irb(main):003:0> puts s
1est
=> nil
irb(main):004:0> sym=:test
=> :test
irb(main):005:0> sym[0]=1
NoMethodError: undefined method `[]=' for :test:Symbol
from (irb):5
irb(main):006:0>
虽然 Symbol 和 String 是不同的对象,但它们之间关系很密切。 Ruby 提供了方法在 Symbol和 String 之间转换。
Symbol 转化为 String
使用 to_s 或 id2name 方法将 Symbol 转化为一个 String 对象:
Symbol 到 String
irb(main):001:0> :test.id2name
=> "test"
irb(main):002:0> :test.to_s
=> "test"
irb(main):003:0> :"I am a boy".to_s
=> "I am a boy"
注意,每个 String 对象都是唯一的,因此对一个 Symbol 调用多次将产生多个 String 对象。
String 转化为 Symbol
除了在字符串前面加冒号,还可以使用 to_sym 或 intern 方法将 String 转化为 Symbol ,如果该 Symbol 已经存在,则直接返回。
String 到 Symbol
irb(main):001:0> var1 = "test".to_sym
=> :test
irb(main):002:0> var2 = "test".intern
=> :test
irb(main):003:0> var1 == var2
=> true
irb(main):004:0>
使用 Symbol
正如前边提到的, Ruby 内部一直在使用 Symbol ,比如 Ruby 程序中的各种名字,Symbol本质上是 Ruby 符号表中的东西。使用 Symbol 处理名字可以降低 Ruby 内存消耗,提高执行速度,这点我们在下一篇文章中会看到。
那么 Symbol 对我们有什么用呢?当然也是内存。使用 String 的开销太大了,因为每一个String 都是一个对象。想想前边的例子,一个字符串每出现一次 Ruby 就会创建一个 String 对象。
通常来讲,当你面临 String 还是 Symbol 的选择时,可以参考以下标准:
如果使用字符串的内容,这个内容可能会变化,使用 String
如果使用固定的名字或者说是标识符,使用 Symbol
那么什么时候我们会用到名字呢?很多时候都会,比如枚举值、关键字(哈希表关键字、方法的参数)等等
作为哈希表的 key
哈希表是 Symbol 应用最为广泛的地方。
在ruby中,哈希和数组类似,一个哈希表是一系列 key/value 对的集合,只不过它的 key 取值范围更广泛,可以是任何对象,比如正则表达式。但通常我们都会取有意义的 key ,比如 String、Symbol 。
下面这个哈希表表示按城市分类的一些机器的集合。
一个哈希表例子
hosts{
'beijing' => 'machine1',
'shanghai' => 'machine2',
'guangzhou' => 'machine3',
'tianjin' => 'machine4',
'shenzhen' => 'machine5'
}
如果要引用 beijing 的机器,使用 hosts['beijing'] 。但如果我们程序中要频繁引用哈希表中 value ,这样就不大好了,因为 Ruby 对每一次字符串引用都会生成一个 String 对象,累积下来这个开销是相当大的。
我们完全可以使用 Symbol ,因为对于这些 key 来讲,我们用的就是名字而已,例如下面hosts[:beijing]
使用 Symbol 作为 key
hosts = {
:beijing => 'machine1',
:shanghai => 'machine2',
:guangzhou => 'machine3',
:tianjin => 'machine4',
:shenzhen => 'machine5'
}
哈希参数
通常我们定义的函数的参数的个数和顺序是写死的,调用函数的时候要确保参数的个数、顺序匹配,有时候这样很不方便,使用哈希参数可以解决这个问题。
ROR 中就大量地运用这种方式,也许你已经看到了,到处都是 Symbol 和哈希。比如:
使用哈希参数的方法调用
link_to 'Show', :action => 'show', :id => product
add_column :products, :price, :decimal,
:precision => 8, :scale => 2, :default => 0
使用哈希参数的方法可以如下定义,前半部分为固定参数,后面为可变参数,或者干脆全采用哈希参数:
哈希参数
def my_method(para1, …, options={})
#your code
end
def my_method(options={})
#your code
end
如果你希望设定一些默认参数,并允许调用者更改这些参数,可以使用哈希对象的 merge! 方法
hsh.merge!( other_hash )。该方法将 other_hash 里内容加到 hsh 中,如果other_hash 与 hsh 有重复的 key ,则 key在 other_hash 中的 value 覆盖 hsh 中对应 key 的 value 。
方法定义-使用默认参数
class Test
def my_method(opts={})
default_opts={:arg1 => 10, :arg2 => "abc"}
default_opts.merge!(opts)
default_opts.each{|key,value| puts "#{key} is #{value}"}
end
end
t = Test.new
t.my_method :arg1=>5, :arg3=>"def"
运行结果
arg1 is 5
arg2 is abc
arg3 is def
原文参考地址:https://blog.csdn.net/besfanfei/article/details/7966850
# 别的网站的讲解
Symbol看起来像一个没有引号的字符串前加了个冒号:myname
当然你也可以用冒号加引号的形式声明带空格的symbol。
:'my name'or :"my name" Symbol是不变的,不可以像其他变量一样对它进行赋值运算。
比如这样的写法是错误的:myname = "Tom"。 相反Symbol可以作为值赋给其他变量比如mystring = :myname。
=end
【【其他文件】】
# 【chop & chomp】
=begin
还没开始系统性的学习Ruby,最近在看metasploit框架的exploit会涉及到Ruby脚本,也就硬着头皮一遍查阅资料一遍做些笔记吧。
Ruby字符串中存在chop和chomp的内置函数。我在http://www.w3cschool.cc/ruby/ruby-string.html中得到的关于Ruby字符串chop和chomp的用法介绍如下:
str.chomp
从字符串末尾移除记录分隔符($/),通常是 \n。如果没有记录分隔符,则不进行任何操作。
str.chomp!
与 chomp 相同,但是 str 会发生变化并返回。
str.chop
移除 str 中的最后一个字符。
str.chop!
与 chop 相同,但是 str 会发生变化并返回。
单从这几句话,还是有些不明白(貌似借鉴于perl语言中的chop和chomp函数的用法),然后百度了一下,我在http://blog.chinaunix.net/uid-20691105-id-1568659.html得到如下内容:
chomp和chop的区别:
chomp:去掉字符串末尾的\n或\r
chop:去掉字符串末尾的最后一个字符,不管是\n\r还是普通字符
"hello".chomp #=> "hello"
"hello\n".chomp #=> "hello"
"hello\r\n".chomp #=> "hello"
"hello\n\r".chomp #=> "hello\n"
"hello\r".chomp #=> "hello"
"hello".chomp("llo") #=> "he"
"string\r\n".chop #=> "string"
"string\n\r".chop #=> "string\n"
"string\n".chop #=> "string"
"string".chop #=> "strin"
首先,可以看到print是不输出换行符的(不会自动换行),但是会解析双引号中的转义字符,
可以看到print输出了字符串中的换行符\n和回车符\r。我之前有点迷惑的是“\r\n”,“\n\r”这两个前后顺序不同时,
chop和chomp函数是如何处理的。从运行的结果看,当字符串最后面跟的是“\r\n”时,”\r\n”都会被去掉,
而当字符串最后面跟的是”\n\r”时,只会去掉回车符。好吧,总算是明白了。
=end
input.txt
suport.rb:
module Week
FIRST_DAY = 'Sunday'
def Week.week_in_month
puts 'you have four weeks in a month'
end
def Week.week_in_year
puts 'you have 52 weeks in a year'
end
end
moral.rb:
module Moral
VERY_BAD = 0
BAD = 1
def Moral.sin(badness)
end
end
#【控制流程】【循环语句】
5.times{
|i|
print "这是第",i,"次","\n"
}
3.times{
print "hi"
}
print "\n"
1.upto(9){
|i|
print i if i < 7
}
print "\n"
9.downto(1){
|i|
print i if i < 7
}
print "\n"
(1..9).each{
|i|
print i if i < 7
}
print "\n"
0.step(11,3){
|i|
print i
}
print "\n"
1.step(11,3){
|i|
print i
}
=begin
这是第0次
这是第1次
这是第2次
这是第3次
这是第4次
hihihi
123456
654321
123456
0369
14710
=end
print "\n"
#【【循环控制】】
i = 0
['Perl','Python','Ruby','Scheme'].each{
|lang|
i += 1
if i == 3
break
end
p [i,lang]
}
=begin
[1, "Perl"]
[2, "Python"]
=end
i = 0
['Perl','Python','Ruby','Scheme'].each{
|lang|
i += 1
if i == 3
redo
end
p [i,lang]
}
=begin
[1, "Perl"]
[2, "Python"]
[4, "Ruby"]
[5, "Scheme"]
=end
i = 0
['Perl','Python','Ruby','Scheme'].each{
|lang|
i += 1
if i == 3
next
end
p [i,lang]
}
=begin
[1, "Perl"]
[2, "Python"]
[4, "Scheme"]
=end
#【【数据类型】】
#例子 数值类型的相互转换
puts 12.to_f #12.0
puts 12.0.to_i #12
#例子 字符串和数值的相互转化
puts "12.34estts".to_f #12.34
puts "12.34esdff".to_i #12
puts 12.34.to_s #"12.34"
puts 12.to_s #12
#浮点数的处理 四舍五入
p 1.2.round #1
p 1.8.round #2
p -1.2.round #-1
p -1.8.round #-2
#浮点数、进位取整。。
p 1.5.ceil #2
p -1.5.ceil #-1
#返回小于或等于num的最大整数
p 1.5.floor #1
p -1.5.floor #-2
#【数组】
#初始化
#B = []
#B = Array.new #Array
#p B.class
#数组的获取
B = [1,2,3]
p B[0] #1
p B[1] #2
#数组运算和常用函数
#& 交集
p [1,1,3,5]&[1,3] #[1, 3]
# *
p [1,2,3] * 3
p [1,2,3] * ' - '
p [1,2,3] * " - "
=begin
[1, 2, 3, 1, 2, 3, 1, 2, 3]
"1 - 2 - 3"
"1 - 2 - 3"
=end
# + 串联
p [1,2,3] + [4,5] #[1, 2, 3, 4, 5]
p [1,2,3,4] + [4,5] #[1, 2, 3, 4, 4, 5]
# - 数组差集 :返回新数组,该数组是原数组的拷贝,并删除了出现再other_array中的元素
p [1,1,2,2,3,3,4,5] - [1,2,4] #[3, 3, 5]
# << 将给定的对象添加到数组的末尾
p [1,2] << "c" << "d" << [4,5] #[1, 2, "c", "d", [4, 5]]
a = [1,2,3,2,1]
a.delete(2)
p a #[1, 3, 1]
a = [1,2,3,2,1]
a.delete_at(2)
p a #[1, 2, 2, 1]
a = [1,[2,[3]],[4],5]
a.flatten!
p a #[1, 2, 3, 4, 5]
a = [2,5,3,5,1]
a.sort!
p a #[1, 2, 3, 5, 5]
#【字符串】
#长度
p "ruby".length #4
p "ruby".size #4
#分割字符串
str = "hello world ! !"
p str.split #["hello", "world", "!", "!"]
p str.split(" ") #["hello", "world", "!", "!"]
#字符串去空格
str = "hello world ! !"
p str.strip #正常应该是"helloworld!!"
str = "hello world ! !"
p str.strip! #正常应该是"helloworld!!"
#字符串替换
str = "hello world !!"
p str.sub("!","ruby") #"hello world ruby!"
str = "hello world !!"
p str.gsub("!","ruby") #"hello world rubyruby"
# 字符串的运算
# *
p "Ho" * 3 #"HoHoHo"
p "hello" + "world" #"helloworld"
# << 把给定的对象串联到str 如果这个对象是一个值在0~255之间的fixnum,在串联之前会把它转成一个字符
a = "hello"
p a << 33
p a << "world"
# 索引,类似数组
str = "abcdef"
p str[0] #"a"
p str[0].chr #"a"
p str[2] #"c"
p str[2].chr #"c"
p str[1,2] #"bc"
p str[1,3] #"bcd"
#【哈希】
#初始化
h = {"R" => "Ruby"}
hash2 = Hash.new
p h["R"] #"Ruby"
#哈希的元素可以是哈希,但哈希的键是唯一的
table = {"A" => {"a" => "x","b" => "y"},"B" => {"a" => "v","b" => "w"}}
p table["A"]["a"] #"x"
p table["B"]["a"] #"v"
#删除元素
h = {"R" => "Ruby"}
h.delete("R")
p h #{}
p h["R"] #nil
#大小
h = {"a" => "b","c" => "d"}
p h.length #2
p h.size #2
#【【正则】】
#匹配
str = "hello,kaichuan,Welcome!"
p str =~ /kaichuan/ #6
p str =~ /a/ #7
p str =~ /ABC/ #nil
#不匹配
str = "hello,kaichuan,Welcom!"
p str !~ /kaichuan/ #false
p str !~ /a/ #false
p str !~ /ABC/ #true
# 知识点 参考地址:https://blog.csdn.net/tse_e/article/details/54930073