字面值
- 数值字面值
- 字符串字面值
- 反斜线表示法
- 展开式
- 命令输出
- 集成字符串(here document)
- 正则表达式字面值
- 数组表达式
- 哈希表表达式
- 范围对象
- 符号
- %表示法
我们把形如数字1或字符串“hello world”这样可以直接写入Ruby程序中的值叫做字面值。
数值字面值
123
0d123
ruby 1.7 特性整数
-123
有符号整数 trap::Numeric
123.45
浮点数 ruby 1.8 特性: 不能把0.1写成".1",而只能完整地写为0.1。
1.2e-3
浮点数
0xffff
16进制整数
0b1011
2进制整数
0377
0o377
ruby 1.7 特性8进制整数
?a
字符
a
的代码(97)ruby 1.7 特性: 用在空白类字符上时,必须写成这样,?\s、?\t等。
?\C-a
Control a 的代码(1)
?\M-a
Meta a 的代码(225)
?\M-\C-a
Meta-Control a 的代码(129)
在?
句中,所有的反斜线表示法都是有效的。
您可以在除了字符代码以外的数值字面值中插入“_”。Ruby解释器会忽视“_”而不作处理。当数值位数非常多时,使用“_”会让您快速看清其位数。但是不能在字面值的前面或后面插入“_”(若在字面值前面(包括(+,-)号与字面值间的位置)插入_时,它会被误认成局部变量或方法调用)。
1_000_000_000 => 1000000000 0xffff_ffff => 0xffffffff
字符串字面值
例:
"this is a string expression\n" 'this is a string expression\n' %q!I said, "You said, 'She said it.'"! %!I said, "You said, 'She said it.'"! %Q('This is it.'\n)
字符串被双引号或单引号包围着。在被双引号中括起来的字符串中,反斜线表示法和展开式(后面详述)都是有效的。在被单引号括起来的字符串中,除了\\(反斜线本身)、\'(单引号)和行尾的\(忽略换行)以外,不会对字符串内容作任何处理。
中间留有空白的字符串在编译时会被当作1个字符串字面值来处理。
p "foo" "bar" => "foobar"
还有其他一些使用%表示法的字符串项目。
每次对字符串表达式进行计算时都会生成新的字符串对象。
反斜线表示法
\t
Tab(0x09)
\n
换行(0x0a)
\r
回车(0x0d)
\f
换页(0x0c)
\b
BackSpace(0x08)
\a
Bell (0x07)
\e
Escape(0x1b)
\s
空白(0x20)
\nnn
8 进制数表示 (n 为 0-7)
\xnn
16 进制数表示 (n 为 0-9,a-f)
\cx
\C-x
Control字符 (x 为 ASCII 字符)
\M-x
Meta x (c | 0x80)
\M-\C-x
Meta Control x
\x
字符 x 本身
展开式
例:
(假设$ruby = "RUBY") "my name is #{$ruby}" #=> "my name is RUBY" 'my name is #{$ruby}' #=> "my name is #{$ruby}"
在以双引号("
)括起来的字符串表达式、命令字符串以及正则表达式中,可以使用“#{表达式}”把表达式的内容(以字符串的形式)嵌入其中。若表达式是以($,@)开始的变量的话,则可以省略{}部分,只使用“#变量名”的形式即可。如果在字符#后出现的是“{,$,@”以外的其他字符的话,字符#仍代表"#"本身。若想显式地阻止展开式的话,在#前添加反斜线即可。
展开式中可以包括双引号和其他的Ruby表达式。注释也可以纳入其中。
p "#{ "string" # comment }" # => "string"
ruby 1.7 特性: 在version 1.7中,展开式中的注释内容开始于“#”终止在行尾,而非“}”。因此,上例应该写成
p "#{ "string" # comment }" # => "string"
这个样子。
命令输出
例:
`date` %x{ date }
被后引号(`
)括起来的字符串与被双引号括起来的字符串是一样的。首先会处理其中的反斜线表示法和展开式,然后才会执行该命令。命令的标准输出是字符串。每次计算命令时都会把它执行一次。若想得到命令的结束status,请参考$?。
还有其他一些使用%表示法的命令输出。
here document - 集成字符串 (多行字符串的字面值)
语法:
<<[-]["'`]标识符["'`] ... 标识符
普通的字符串字面值是指使用分隔符(", ', ` 等)括起来的字符串部分。集成字符串是指,把从包含“<<标识符”的行的下一行开始,到只包含“标识符”的行的行首之间的内容封装起来之后得到的多行字符串(的字面值)。例如
print <<EOS # (从这里开始)直到标识符 EOS 之前的部分就是字面值 the string next line EOS
等同于下例
print " the string\n next line\n"
集成字符串中的开始标签“<<标识符”具有非常重要的语法意义。您可以使用开始标签,将集成字符串的内容传递给某参数,或者把集成字符串本身当作被调(receiver)使用。
# 在表达式中加入开始标签 # 把集成字符串的内容传递给method的第2个参数 method(arg1, <<LABEL, arg2) 集成字符串的具体内容 LABEL # 将集成字符串用作被调 p <<LABEL.upcase the lower case string LABEL # => "THE LOWER CASE STRING"
开始标签的下一行通常是集成字符串的具体内容。例如,下面的写法是错误的。
printf('%s%d', <<EOS, 3055 * 2 / 5) # <- 该行已经混入集成字符串的内部 This line is a here document. EOS
若把开始标签写成“<<-标识符”的话,表示集成字符串的最后一行将使用缩进格式。除此以外,您不能在最后一行中加入空白或是注释。
if need_define_foo eval <<-EOS # 使用'<<-'后 def foo print "foo\n" end EOS #↑最后一行使用了缩进格式。 end
您还可以在同一行中使用多个集成字符串。
print <<FIRST, <<SECOND 这里是第一个集成字符串的内容。 这里也是。 FIRST 从该行开始第二个集成字符串的内容。 第二个集成字符串将在本行后面结束。 SECOND
您可以使用引号(""、''或``)将开始标签“<<标识符”中的标识符括起来。这时,集成字符串的性质将取决于您所选择的引号的种类。请参考下列,当您选择双引号时,其效果与不使用任何引号时的效果相同。
# 反斜线表示法和展开式都是有效的 print <<"EOS" The price is #{$price}. EOS # 效果同上 print <<EOS The price is #{$price}. EOS # 展开式无法工作 print <<'EOS' The price is #{$price}. EOS # 执行命令 print <<`EOC` date diff test.c.org test.c EOC
请参考 字符串字面值、 展开式、 反斜线表示法、 命令输出 来了解字符串字面值的性质
正则表达式字面值
例:
/^Ruby the OOPL/ /Ruby/i /my name is #{myname}/o %r|Ruby|
被/括起来的部分就是正则表达式。关于正则表达式中元字符的用法问题,请参考正则表达式。
尾部/后面的字符是正则表达式中使用的选项。具体内容如下。
i
匹配时不区分字母大小写
o
开始计算正则表达式时只处理一次展开式
x
正则表达式中的空白(包括换行)将被忽视。同时,从"#"到行尾的部分将被当作注释处理(请注意,若注释中包含/则会引起语法解析错误)。
/foo # 注释 bar/x
等同于
/foobar/
。若想包含空白,可以像\一样使用转义。
m
多行模式。正则表达式 "."将会匹配换行。
因为Ruby的日语化做得比较好,您可以设定$KCODE使其能够正确处理日语字符。若$KCODE =“n”时,Ruby将不会识别任何日语字符,而把它们当作字节串处理,这是默认状态。
您还可以摆脱$KCODE的束缚,分别为每个正则表达式指定n
,e
,s
,u
中的任意一个选项来确定该正则表达式的字符代码。
您还可以使用%表示法来指定其他形式的正则表达式。
在正则表达式中,反斜线表示法和 展开式也是有效的。
若正则表达式字面值中不含展开式的话,则对其进行计算时始终返回同一个正则表达式对象。若含有展开式的话,则每次(以展开式的结果为基础)进行计算时都会编译正则表达式并生成正则表达式对象(但是,若指定了上述的o选项的话,则返回同一个正则表达式对象)。
数组表达式
例:
[1, 2, 3] %w(a b c) %W(a b c) ((<ruby 1.7 特性>))
语法:
`[' 表达式`,' ... `]'
分别计算每个表达式的值,然后返回由这些值构成的数组。数组是Array类的实例。
当数组元素都是字符串字面值时,可以使用%表示法将数组写成其他形式。
每次对数组表达式进行计算时都会返回一个新的数组对象。
哈希表表达式
例:
{1=>2, 2=>4, 3=>6}
语法:
`{' 表达式 `=>' 表达式 `,' ... `}' `{' 表达式 `,' 表达式 `,' ... `}'
分别计算每个表达式的值,然后返回由索引和值构成的哈希表对象。所谓哈希表是指将任意对象当作索引而构成的数组,它是Hash类的实例。
当向某方法的参数尾部传递哈希表,且该哈希表中的元素超过1个时,可以省略{,}。但是,在形如obj[...]的方法调用以及数组表达式中,当所有元素都是哈希表时,才可以省略{,}。
例:
method(1,2,3=>4) # method(1,2,{3=>4}) obj[1=>2,3=>4] # obj[{1=>2,3=>4}] [1=>2,3=>4] # [{1=>2, 3=>4}]
每次对哈希表表达式进行计算时都会生成一个新的哈希表对象。
范围对象
请参考范围表达式
若范围表达式两端都是数值字面值时,每次计算都将返回同一个对象。除此以外,每次计算时都会返回新的范围对象。
符号
例:
(符号的例子) :class :lvar :method! :andthisis? :$gvar :@ivar :@@cvar :+
语法:
`:' 标识符 `:' 变量名 `:' 操作符
Symbol类的实例。字符串与Symbol
对象是一一对应的。
指定给Symbol字面值的操作符,必须是那些可以作为方法进行再定义的操作符。请参考操作符表达式。
ruby 1.7 特性: 在1.7中,也可以这样
p :'foo-bar' #=> :"foo-bar" p :"foo-bar" #=> :"foo-bar" p %s{foo-bar} #=> :"foo-bar"
在这种表示法中,可以定义任意的符号(但不能包含“\0”)。
在:"..."
中,反斜线表示法和 展开式都是有效的。
通常符号是一种很专一的对象,计算时(就算包含展开式也好,只要其结果是同一字符串的话)总是返回同一对象。
%表示法
在字符串字面值、 命令输出、 正则表达式字面值、 数组表达式、 符号 中,可以使用这种以%开头的表达法。特别是当字符串或正则表达式中包含双引号(")、斜线(/)等(切分字面值时使用的字符)要素时,它可以减少反斜线(\)在代码中出现的次数。另外,它还可以方便地表示字符串数组。详细内容如下。
%!STRING!
: 双引号中的字符串%Q!STRING!
: 同上%q!STRING!
: 单引号中的字符串%x!STRING!
: 命令输出%r!STRING!
: 正则表达式%w!STRING!
: 字符串数组(以空白字符切分各元素)%W!STRING!
: 字符串数组(以空白字符切分各元素)。展开式、反斜线表示法都有效(ruby 1.7 特性)%s!STRING!
: 符号。展开式、反斜线表示法都无效(ruby 1.7 特性)
!
部分可以使用任何非字母非数字的字符,包括换行。若起始切分字符是括号("(","[","{","<")的话,则终止切分字符就是与其对应的括号。若以括号作为切分字符的话,只要对应部分使用了对应的括号,就可以在其中的元素中使用与切分字符一样的括号。
%(()) => "()"
若在数组表达式中使用%表示法的话,相当于使用空白字符将数组中以单引号括起来的字符串元素分隔开来。例如,
%w(foo bar baz)
与['foo', 'bar', 'baz']
是一样。
还可以使用反斜线将空白字符纳入数组元素。
%w(foo\ bar baz) => ["foo bar", "baz"]
ruby 1.7 特性:%W与%w相同,就如同双引号中的字符串一样,可以使用展开式和反斜线表示法。但使用空白字符进行切分的过程要早于展开式的计算过程。
v = "c d" %W(a\ b #{v}e\sf #{}) => ["a b", "c de f", ""]