那么看看还有哪些方法会修改左边字符串的值, (一般以!结尾的方法是会修改左边字符串的值的)
s = "hello world"
print( "1) s='#{s}' and s.object_id=#{s.object_id}\n" )
s = s + "!" # this creates a new string object
print( "2) s='#{s}' and s.object_id=#{s.object_id}\n" )
s = s.capitalize # this creates a new string object
print( "3) s='#{s}' and s.object_id=#{s.object_id}\n" )
s.capitalize! # but this modifies the original string object
print( "4) s='#{s}' and s.object_id=#{s.object_id}\n" )
s[1] = 'A' # this also modifies the original string object
print( "5) s='#{s}' and s.object_id=#{s.object_id}\n" )
s << ' Digoal' # this also modifies the original string object
print( "6) s='#{s}' and s.object_id=#{s.object_id}\n" )
执行结果 :
1) s='hello world' and s.object_id=15923760 # 给String的对象赋值(不管这个值是否与原来的值相等)会改变object_id
2) s='hello world!' and s.object_id=15923664
3) s='Hello world!' and s.object_id=15923592 # 以下几个操作之后, object_id都没有变化, 但是s的值已经被修改了.
4) s='Hello world!' and s.object_id=15923592
5) s='HAllo world!' and s.object_id=15923592
6) s='HAllo world! Digoal' and s.object_id=15923592
给Fixnum和String的对象赋值。看看object_id会不会发送改变 :
i1 = 10
s1 = "Digoal"
puts(i1.class)
puts(i1.object_id)
puts(s1.class)
puts(s1.object_id)
# 以变量的形式赋值给新的变量, 看看新变量的object_id, 等于前者的OBJECT_ID
i2 = i1
s2 = s1
puts(i2.object_id)
puts(s2.object_id)
# 使用相同的值赋值给新的变量, String新变量的object_id与前者不同. 但是Fixnum类的对象的object_id相同.
i3 = 10
s3 = "Digoal"
puts(i3.object_id)
puts(s3.object_id)
# 使用相同的值覆盖相同的变量, 看看object_id会不会变化, String类的对象的object_id会变化, Fixnum类的对象只要值一样, OBJECT_ID都一样.
i3 = 10
s3 = "Digoal"
puts(i3.object_id)
puts(s3.object_id)
执行结果 :
Fixnum
21
String
16221864
21
16221864
21
16221600
21
16221516
7. Indexing into a String
一个字符串, 其中的每个字符都有一个标记, 从0开始. 来看个例子 :
s = "Hello"
length = s.length
(0...length).each { # 三个点的Range类不包含最大值.
|x|
puts(s[x])
}
执行结果 :
H
e
l
l
o
注意1.8中用s[x]输出的是字符的ASCII值, 1.9输出的是字符本身. 如果要在1.9中输出ASCII怎么办呢, 用ord方法.
s = "Hello"
puts(s[0])
puts(s[0].ord)
执行结果 :
H
72
还有一个玩法 :
s = "Hello , I'm Digoal"
puts(s[0,4]) # 从0开始, 输出4个字符.
puts(s[-6,6]) # 从倒数第6个开始, 输出6个字符.
puts(s[(1...4)]) # 从1到4, 不包括4.
puts(s[(1..4)]) # 从1到4, 包括4
puts(s[(-6..-1)]) # 从-6到-1. 包括-6和-1
执行结果 :
Hell
Digoal
ell
ello
Digoal
接下来列举一些String类的方法 :
当然你可以使用String.methods打印出来看看到底有多少方法, 然后到API里面去学习它们的用法 :
s = "Hello , I'm Digoal"
puts(s.length)
puts(s.reverse!)
puts(s.reverse)
puts(s.upcase)
puts(s.capitalize)
puts(s.swapcase)
puts(s.downcase)
puts(s.insert(7,"NOT ")) # 注意这里的7是从0开始的哦,不是从1开始的. 是在index 7 之前插入的意思.
puts(s.squeeze)
puts(s.split)
输出结果 :
18
laogiD m'I , olleH
Hello , I'm Digoal
LAOGID M'I , OLLEH
Laogid m'i , olleh
LAOGId M'i , OLLEh
laogid m'i , olleh
laogiD NOT m'I , olleH
laogiD NOT m'I , oleH
laogiD
NOT
m'I
,
olleH
8. chomp(safer) and chop
先介绍一个$/ , 默认是\n. ASCII码=10. 这个字符串可以修改, 用于gets()时, 表示$/以后的字符不接收. $/本身接收 .
用在chomp()方法, 在末尾时可以去除这个字符串.
puts($/.class)
puts($/.ord)
执行结果 :
String
10
chomp用于去除字符串末尾的\n, \r 或 \r\n. 或者$/, \n$/, \r$/, \r\n$/
$/ = "ok"
puts("let's go0ok".chomp())
puts("let's go1\r\nok".chomp())
puts("let's go2\nok".chomp())
puts("let's go3\rok".chomp())
puts("let's go4\r".chomp())
puts("let's go5\n".chomp())
puts("let's go6\r\n".chomp())
# 以下则不能全部去除
puts("let's go7\n\r".chomp())
puts("let's go8ok\n".chomp())
puts("let's go9ok\r\n".chomp())
执行结果 :
let's go0
let's go1
let's go2
let's go3
let's go4
let's go5
let's go6
let's go7
let's go8ok
let's go9ok
chop则是用于去除最后一个字符的, 不管是什么字符.
$/ = "ok"
puts("let's go0ok".chop())
执行结果 :
let's go0o
再举一个gets()的例子 :
#!/opt/ruby/bin/ruby
$/ = "ok"
s = gets()
puts(s)
输入 :
jfjjsj
nioooo few ok ffewww good ok回车, # 第一个ok就表示记录结束了.
执行结果 :
jfjjsj
nioooo few ok
9. Format Strings ( printf )
printf()方法的格式化输出 :
%d – decimal number
%f – floating-point number
%o – octal number
%p – inspect object
%s – string
%x – hexadecimal number
printf( "%f\n", 10.12945 )
printf( "%0.2f\n", 10.12945 )
printf("d=%d f=%f o=%o x=%x s=%s\n", 10, 10, 10, 10, 10)
printf("0.04f=%0.04f : 0.02f=%0.02f\n", 10.12945, 10.12945)
class Myclass
def initialize(a,b)
@x = a
@y = b
end
attr_accessor( :x, :y )
end
ob1 = Myclass.new('digoal','zhou')
printf("inspect ob1: %p.\n",ob1)
执行结果 :
10.129450
10.13
d=10 f=10.000000 o=12 x=a s=10
0.04f=10.1295 : 0.02f=10.13
inspect ob1: #<Myclass:0x1fb0960 @x="digoal", @y="zhou">.
10. Range
Range在Ruby中非常有意思, 在PostgreSQL 中用generate_series函数可以产生一连串的数字, 时间等.
在Ruby中用Range可以产生一串数字, 字符串, 浮点数等.
r1 = (1..10) # 两个点表示包含最大和最小值
puts( r1.class )
puts( r1 )
puts( r1.count )
r2 = (1...10) # 三个点表示不包含最大值
puts( r2.class )
puts( r2 )
puts( r2.count )
执行结果 :
Range
1..10
10
Range
1...10
9
把Range对象转换成Array对象 : (注意浮点型的Range对象不可以转换成Array对象, 会报错, 因为可能包含无穷数)
r1 = (1..10)
r2 = ('abc'..'def')
a1 = r1.to_a # to_a方法用于将Range对象转换成Array对象.
a2 = r2.to_a
puts(a1.class)
puts(a2.class)
puts(a1)
执行结果 :
Array
Array
1
2
3
4
5
6
7
8
9
10
11. Iterating with a Range
其实Range和Array, Hash类型都有Iterate操作的. 来看个例子 :
r1 = ('a'..'z')
r1.each { # 一个块,块非对象
|x| # 这是一个BLOCK内的变量.
print(x)
}
执行结果 :
abcdefghijklmnopqrstuvwxyz
12. Multi-line Strings ( <<EODOC )
多行字符串, 其实有点类似SHELL的玩法 :
s1 = <<EODOC # 也可以写成<<'EODOC' , 则表示内部的字符串是用单引号包围的.
The first line.
The second line.
The third line.
... and so on
EODOC # EODOC必须在行首, 如果要不放行首, 可以在前面定义<<EODOC时改用<<-EODOC. 或者<<-'EODOC'
puts(s1)
执行结果 :
The first line.
The second line.
The third line.
... and so on
当然也可以不叫EODOC, 例如<<EOF也行, 结束时使用EOF.
13. String Literals
这个玩法也和有意思, 和前面我们已经用到的%x//, %q//, %Q// 相似, 还有一些其他的玩法. 列举如下 :
%q/ / # single-quoted
%Q/ / # double-quoted
%/ / # double-quoted
%w/ / # array
%W/ / # array double-quoted
%r| | # regular expression
%s/ / # symbol
%x/ / # operating system command
p %q/dog cat #{1+2}/ #=> "dog cat \#{1+2}"
p %Q/dog cat #{1+2}/ #=> "dog cat 3"
p %/dog cat #{1+2}/ #=> "dog cat 3"
p %w/dog cat #{1+2}/ #=> ["dog", "cat", "\#{1+2}"]
p %W/dog cat #{1+2}/ #=> ["dog", "cat", "3"]
p %r|^[a-z]*$| #=> /^[a-z]*$/
p %s/dog/ #=> :dog
p %x/vol/ #=> " Volume in drive C is OS [etc...]"
【参考】
The Book Of Ruby
Ruby 1.9.3 API