非常教程

Ruby 2.4参考手册

语言 | 3Language

Control Expressions

Ruby 有多种方式来控制执行。这里描述的所有表达式都返回一个值。

对于这些控制表达式中的测试,nil并且false是假值true和任何其他对象都是真值。在这个文件中,“真”意味着“真值”和“假”意味着“假值”。

if 表达

最简单的if表达式有两个部分,一个是 “test” 表达式和一个 “then” 表达式。如果“测试”表达式评估为真,则评估“那么”表达式。

这是一个简单的 if 语句:

if true then
  puts "the test resulted in a true-value"
end

这将打印出“测试结果为真实值”。

then是可选的:

if true
  puts "the test resulted in a true-value"
end

本文档将省略then所有表达式的可选项,因为这是最常见的用法if

你也可以添加一个else表达式。如果测试未评估为真,则else表达式将被执行:

if false
  puts "the test resulted in a true-value"
else
  puts "the test resulted in a false-value"
end

这将打印出“测试结果为假值”。

您可以使用添加任意数量的额外测试到 if 表达式elsif。一个elsif当上述所有测试执行elsif都是假的。

a = 1

if a == 0
  puts "a is zero"
elsif a == 1
  puts "a is one"
else
  puts "a is some other value"
end

这将打印“一个是” 1不等于0。由于else仅在没有匹配条件时执行。

一旦条件匹配,if条件或任何elsif条件,if表达式就完成了,不再执行进一步的测试。

像一个if,一个elsif条件可能会跟着一个then

在这个例子中只有“a is one”被打印出来:

a = 1

if a == 0
  puts "a is zero"
elsif a == 1
  puts "a is one"
elsif a >= 1
  puts "a is greater than or equal to one"
else
  puts "a is some other value"
end

测试ifelsif可能有副作用。副作用最常见的用途是将值缓存到局部变量中:

if a = object.some_value
  # do something to a
end

if表达式的结果值是表达式中执行的最后一个值。

Ternary if

你也可以使用?和写一个 if-then-else 表达式:。这三元如果:

input_type = gets =~ /hello/i ? "greeting" : "other"

与此if表达式相同:

input_type =
  if gets =~ /hello/i
    "greeting"
  else
    "other"
  end

虽然三元 if 比写得比较冗长的形式要短得多,但为了便于阅读,建议三元if仅用于简单条件。此外,避免在同一表达式中使用多个三元条件,因为这可能会造成混淆。

unless 表达

unless表达式是相反if的表达。如果该值为 false,则执行 “then” 表达式:

unless true
  puts "the value is a false-value"
end

这不会打印任何内容,因为 true 不是假值。

您可以使用一个可选的thenunless一样if

请注意,上述unless表达式与以下内容相同:

if not true
  puts "the value is a false-value"
end

就像if表达式一样,您可以使用以下else条件unless

unless true
  puts "the value is false"
else
  puts "the value is true"
end

这从else条件打印出“值为真” 。

您不得使用elsifunless表达。

unless表达式的结果值是表达式中执行的最后一个值。

修饰符ifunless

if并且unless也可以被用于修改的表达式。当用作修饰符时,左边是 “then” 表达式,右边是 “test” 表达式:

a = 0

a += 1 if a.zero?

p a

这将打印1。

a = 0

a += 1 unless a.zero?

p a

这将打印0。

虽然修饰符和标准版本同时具有“测试”表达式和“然后”表达式,但由于解析顺序,它们并不是彼此的精确转换。以下是一个显示不同之处的例子:

p a if a = 0.zero?

这引发了 NameError“ 未定义的局部变量或方法`a'”。

当 ruby 分析这个表达式时,它首先会a在 “then” 表达式中遇到一个方法调用,然后它会a在 “test” 表达式中看到该赋值并将其标记a为局部变量。

当运行这条线时,它首先执行“测试”表达式a = 0.zero?

由于测试是真的,它执行“then”表达式,p a。由于a在体内被记录为不存在的方法,所以引发了 NameError。

同样如此unless

case 表达

case表达式可以以两种方式使用。

最常见的方法是将对象与多种模式进行比较。这些模式使用+ === +方法进行匹配,该方法在 Object 上使用别名+ == +。其他类必须覆盖它以提供有意义的行为。有关示例,请参阅模块#===和正则表达式#===。

下面是一个case用来比较 String 和模式的例子:

case "12345"
when /^1/
  puts "the string starts with one"
else
  puts "I don't know what the string starts with"
end

这里通过调用返回值"12345"来比较字符串。与表达式一样,匹配的第一个匹配被执行,所有其他匹配都被忽略。/^1//^1/ === "12345"trueifwhen

如果找不到匹配项,else则执行。

elsethen是可选的,case表达产生相同的结果与上述一个:

case "12345"
when /^1/
  puts "the string starts with one"
end

你可以在同一个地方放置多个条件when

case "2"
when /^1/, "2"
  puts "the string starts with one or is '2'"
end

Ruby 会依次尝试每个条件,所以首先/^1/ === "2"返回false,然后"2" === "2"返回true,所以打印出“字符串以1开头或者是'2'”。

你可以thenwhen条件后使用。这是最经常用来放置when在一条线上的主体。

case a
when 1, 2 then puts "a is one or two
when 3    then puts "a is three"
else           puts "I don't know what a is"
end

使用case表达式的另一种方式就像是一个 if-elsif 表达式:

a = 2

case
when a == 1, a == 2
  puts "a is one or two"
when a == 3
  puts "a is three"
else
  puts "I don't know what a is"
end

再次,thenelse是可选的。

case表达式的结果值是表达式中执行的最后一个值。

while 循环

while循环执行,而条件为真:

a = 0

while a < 10 do
  p a
  a += 1
end

p a

打印数字0到10. a < 10在进入循环之前检查条件,然后执行主体,然后再次检查条件。当条件结果为 false 时,循环终止。

do关键字是可选的。以下循环等同于上面的循环:

while a < 10
  p a
  a += 1
end

while循环的结果是nil除非break用于提供值。

until 循环

until循环执行,而条件是假的:

a = 0

until a > 10 do
  p a
  a += 1
end

p a

这会打印数字0到11.与 while 循环一样a > 10,进入循环时每次执行循环体时都会检查条件。如果条件为假,循环将继续执行。

while循环一样,do是可选的。

while循环一样,循环的结果until是零,除非break被使用。

for 循环

for循环由for一个变量组成,后面跟着一个变量以包含迭代参数,后面跟着in使用每个参数迭代的值。do是可选的:

for value in [1, 2, 3] do
  puts value
end

打印1,2和3。

喜欢whileuntil,这do是可选的。

for循环类似于使用每一个,但不创建一个新的变量范围。

除非break使用for循环的结果值是迭代的值。

for循环在现代 Ruby 程序很少使用。

修饰符whileuntil

ifunlesswhile并且until可以用作改性剂:

a = 0

a += 1 while a < 10

p a # prints 10

until 用作修饰词:

a = 0

a += 1 until a > 10

p a # prints 11

您可以使用beginend创建一个while循环,在条件之前运行一次该主体:

a = 0

begin
  a += 1
end while a < 10

p a # prints 10

如果你不使用rescue或者ensure,Ruby 优化任何异常处理开销。

break Statement

使用break可以尽早离开。values如果其中一个是偶数,这将停止迭代项目:

values.each do |value|
  break if value.even?

  # ...
end

您也可以while使用break以下命令终止循环:

a = 0

while true do
  p a
  a += 1

  break if a < 10
end

p a

这将打印数字0和1。

break 接受一个值,该值提供表达式结果“破坏”的结果:

result = [1, 2, 3].each do |value|
  break value * 2 if value.even?
end

p result # prints 4

next Statement

使用next跳过当前迭代的其余部分:

result = [1, 2, 3].map do |value|
  next if value.even?

  value * 2
end

p result # prints [2, nil, 6]

next 接受可用作当前块迭代结果的参数:

result = [1, 2, 3].map do |value|
  next value if value.even?

  value * 2
end

p result # prints [2, 2, 6]

redo Statement

使用redo重做当前迭代:

result = []

while result.length < 10 do
  result << result.length

  redo if result.last.even?

  result << result.length + 1
end

p result

这会打印 0,1,3,3,5,5,7,7,9,9,11

在Ruby 1.8中,你也可以使用retry你使用的地方redo。这不再是真实的,现在当您retryrescue块外部使用时,您将收到 SyntaxError 。请参阅例外以正确使用retry

Flip-Flop

触发器是一个罕见的条件表达式。它的主要用途是用于从使用 ruby 一个行程序处理的文本ruby -nruby -p

触发器的形式是表示何时触发器打开的表达式,..(或...)表示何时触发器将关闭的表达式。当触发器处于打开状态时,它将继续评估truefalse关闭。

这里是一个例子:

selected = []

0.upto 10 do |value|
  selected << value if value==2..value==8
end

p selected # prints [2, 3, 4, 5, 6, 7, 8]

在上面的例子中,开启条件是n==2。触发器最初关闭(假)为0和1,但在2时开启(真),并保持在8上.8关闭后,关闭9和10。

触发器必须条件这样的里面被用作ifwhileunlessuntil等,包括改性剂的形式。

当您使用包含范围(..)时,关闭条件在条件更改时进行评估:

selected = []

0.upto 5 do |value|
  selected << value if value==2..value==2
end

p selected # prints [2]

在这里,触发器的两端都被评估,所以触发器只有在value等于2 时才会打开和关闭。由于触发器在迭代中打开,它将返回 true。

当您使用独占范围(...)时,关闭条件将在以下迭代中进行评估:

selected = []

0.upto 5 do |value|
  selected << value if value==2...value==2
end

p selected # prints [2, 3, 4, 5]

这里,触发器在value等于2 时打开,但在同一次迭代中不关闭。关闭条件不会被评估,直到接下来的迭代,并且value永远不会再是两次。

Ruby 2.4

Ruby 是一种面向对象、命令式、函数式、动态的通用编程语言,是世界上最优美而巧妙的语言。

主页 https://www.ruby-lang.org/
源码 https://github.com/ruby/ruby
版本 2.4
发布版本 2.4.1

Ruby 2.4目录

1.缩略 | Abbrev
2.ARGF
3.数组 | Array
4.Base64
5.基本对象 | BasicObject
6.基准测试 | Benchmark
7.BigDecimal
8.绑定 | Binding
9.CGI
10.类 | Class
11.比较 | Comparable
12.负责 | Complex
13.计算续体 | Continuation
14.覆盖 | Coverage
15.CSV
16.日期 | Date
17.日期时间 | DateTime
18.DBM
19.代理 | Delegator
20.摘要 | Digest
21.Dir
22.DRb
23.编码 | Encoding
24.枚举 | Enumerable
25.枚举 | Enumerator
26.ENV
27.ERB
28.错误 | Errors
29.Etc
30.期望值 | Exception
31.错误类 | FalseClass
32.Fiber
33.Fiddle
34.文件 | File
35.文件实用程序 | FileUtils
36.查找 | Find
37.浮点 | Float
38.Forwardable
39.GC
40.GDBM
41.GetoptLong
42.Hash
43.Integer
44.IO
45.IPAddr
46.JSON
47.Kernel
48.语言 | 3Language
49.记录 | Logger
50.编排 | Marshal
51.MatchData
52.数学 | Math
53.矩阵 | Matrix
54.方法 | Method
55.模型 | Module
56.监控 | Monitor
57. 互斥 | Mutex
58.Net
59.Net::FTP
60.Net::HTTP
61.Net::IMAP
62.Net::SMTP
63.NilClass
64.数字 | Numeric
65.对象 | Object
66.ObjectSpace
67.Observable
68.Open3
69.OpenSSL
70.OpenStruct
71.OpenURI
72.OptionParser
73.路径名 | Pathname
74.完整输出 | PrettyPrint
75.Prime
76.Proc
77.过程 | Process
78.PStore
79.PTY
80.队列 | Queue
81.随机 | Random
82.范围 | Range
83.合理的 | Rational
84.Readline
85.Regexp
86.Resolv
87.Ripper
88.RubyVM
89.Scanf
90.SDBM
91.SecureRandom
92.Set
93.Shell
94.信号 | Signal
95.Singleton
96.套接字 | Socket
97.字符串 | String
98.StringIO
99.StringScanner
100.结构 | Struct