Ruby学习笔记7.Ruby 循环及方法

Posted 海棠赠微雨.

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Ruby学习笔记7.Ruby 循环及方法相关的知识,希望对你有一定的参考价值。

前言

本章介绍Ruby的循环和方法。

Ruby 循环

Ruby 中的循环用于执行相同的代码块若干次。本章节将详细介绍 Ruby 支持的所有循环语句。

Ruby while 语句
语法

while conditional [do]
   code
end

或者

语法

while conditional [:]
   code
end

当 conditional 为真时,执行 code。

语法中 do 或 : 可以省略不写。但若要在一行内写出 while 式,则必须以 do 或 : 隔开条件式或程式区块。

实例

#!/usr/bin/ruby
# -*- coding: UTF-8 -*-
 
$i = 0
$num = 5
 
while $i < $num  do
   puts("在循环语句中 i = #$i" )
   $i +=1
end

以上实例输出结果为:

在循环语句中 i = 0
在循环语句中 i = 1
在循环语句中 i = 2
在循环语句中 i = 3
在循环语句中 i = 4

Ruby while 修饰符
语法

code while condition
 
或者
 
begin 
  code 
end while conditional

当 conditional 为真时,执行 code。

如果 while 修饰符跟在一个没有 rescue 或 ensure 子句的 begin 语句后面,code 会在 conditional 判断之前执行一次。

实例

#!/usr/bin/ruby
# -*- coding: UTF-8 -*-
 
$i = 0
$num = 5
begin
   puts("在循环语句中 i = #$i" )
   $i +=1
end while $i < $num

以上实例输出结果为:

在循环语句中 i = 0
在循环语句中 i = 1
在循环语句中 i = 2
在循环语句中 i = 3
在循环语句中 i = 4

Ruby until 语句
语法

until conditional [do]
   code
end

当 conditional 为假时,执行 code。

语法中 do 可以省略不写。但若要在一行内写出 until 式,则必须以 do 隔开条件式或程式区块。

实例

#!/usr/bin/ruby
# -*- coding: UTF-8 -*-
 
$i = 0
$num = 5
 
until $i > $num  do
   puts("在循环语句中 i = #$i" )
   $i +=1;
end

以上实例输出结果为:

在循环语句中 i = 0
在循环语句中 i = 1
在循环语句中 i = 2
在循环语句中 i = 3
在循环语句中 i = 4
在循环语句中 i = 5

Ruby until 修饰符
语法

code until conditional
 
或者
 
begin
   code
end until conditional

当 conditional 为 false 时,执行 code。

如果 until 修饰符跟在一个没有 rescue 或 ensure 子句的 begin 语句后面,code 会在 conditional 判断之前执行一次。

实例

#!/usr/bin/ruby
# -*- coding: UTF-8 -*-
 
$i = 0
$num = 5
begin
   puts("在循环语句中 i = #$i" )
   $i +=1;
end until $i > $num

以上实例输出结果为:

在循环语句中 i = 0
在循环语句中 i = 1
在循环语句中 i = 2
在循环语句中 i = 3
在循环语句中 i = 4
在循环语句中 i = 5

Ruby for 语句
语法

for variable [, variable ...] in expression [do]
   code
end

先计算表达式得到一个对象,然后针对 expression 中的每个元素分别执行一次 code。

实例

#!/usr/bin/ruby
# -*- coding: UTF-8 -*-
 
for i in 0..5
   puts "局部变量的值为 #i"
end

在这里,我们已经定义了范围 0…5。语句 for i in 0…5 允许 i 的值从 0 到 5(包含 5)。

以上实例输出结果为:

局部变量的值为 0
局部变量的值为 1
局部变量的值为 2
局部变量的值为 3
局部变量的值为 4
局部变量的值为 5

for…in 循环几乎是完全等价于:

(expression).each do |variable[, variable...]| code end

但是,for 循环不会为局部变量创建一个新的作用域。

语法中 do 可以省略不写。但若要在一行内写出 for 式,则必须以 do 隔开条件式或程式区块。

实例

#!/usr/bin/ruby
# -*- coding: UTF-8 -*-
 
(0..5).each do |i|
   puts "局部变量的值为 #i"
end

以上实例输出结果为:

局部变量的值为 0
局部变量的值为 1
局部变量的值为 2
局部变量的值为 3
局部变量的值为 4
局部变量的值为 5

Ruby break 语句
语法

break

终止最内部的循环。如果在块内调用,则终止相关块的方法(方法返回 nil)。

实例

#!/usr/bin/ruby
# -*- coding: UTF-8 -*-
 
for i in 0..5
   if i > 2 then
      break
   end
   puts "局部变量的值为 #i"
end

以上实例输出结果为:

局部变量的值为 0
局部变量的值为 1
局部变量的值为 2

Ruby next 语句
语法

next

跳到循环的下一个迭代。如果在块内调用,则终止块的执行(yield 表达式返回 nil)。

实例

#!/usr/bin/ruby
# -*- coding: UTF-8 -*-
 
for i in 0..5
   if i < 2 then
      next
   end
   puts "局部变量的值为 #i"
end

以上实例输出结果为:

局部变量的值为 2
局部变量的值为 3
局部变量的值为 4
局部变量的值为 5

Ruby redo 语句
语法

redo

重新开始最内部循环的该次迭代,不检查循环条件。如果在块内调用,则重新开始 yield 或 call。

实例

#!/usr/bin/ruby
# -*- coding: UTF-8 -*-
 
for i in 0..5
   if i < 2 then
      puts "局部变量的值为 #i"
      redo
   end
end

这将产生以下结果,并会进入一个无限循环:

局部变量的值为 0
局部变量的值为 0
............................

Ruby retry 语句
注意:1.9以及之后的版本不支持在循环中使用retry。

语法

retry

如果 retry 出现在 begin 表达式的 rescue 子句中,则从 begin 主体的开头重新开始。

begin
   do_something   # 抛出的异常
rescue
   # 处理错误
   retry          # 重新从 begin 开始
end

如果 retry 出现在迭代内、块内或者 for 表达式的主体内,则重新开始迭代调用。迭代的参数会重新评估。

for i in 1..5
   retry if some_condition # 重新从 i == 1 开始
end

实例

#!/usr/bin/ruby
# -*- coding: UTF-8 -*-
 
for i in 1..5
   retry if  i > 2
   puts "局部变量的值为 #i"
end

这将产生以下结果,并会进入一个无限循环:

局部变量的值为 1
局部变量的值为 2
局部变量的值为 1
局部变量的值为 2
局部变量的值为 1
局部变量的值为 2
............................

Ruby 方法

Ruby 方法与其他编程语言中的函数类似。Ruby 方法用于捆绑一个或多个重复的语句到一个单元中。

方法名应以小写字母开头。如果您以大写字母作为方法名的开头,Ruby 可能会把它当作常量,从而导致不正确地解析调用。

方法应在调用之前定义,否则 Ruby 会产生未定义的方法调用异常。

语法

def method_name [( [arg [= default]]...[, * arg [, &expr ]])]
   expr..
end

所以,您可以定义一个简单的方法,如下所示:

def method_name 
   expr..
end

您可以定义一个接受参数的方法,如下所示:

def method_name (var1, var2)
   expr..
end

您可以为参数设置默认值,如果方法调用时未传递必需的参数则使用默认值:

def method_name (var1=value1, var2=value2)
   expr..
end

当您要调用方法时,只需要使用方法名即可,如下所示:

method_name

但是,当您调用带参数的方法时,您在写方法名时还要带上参数,例如:

method_name 25, 30

使用带参数方法最大的缺点是调用方法时需要记住参数个数。例如,如果您向一个接受三个参数的方法只传递了两个参数,Ruby 会显示错误。

实例

#!/usr/bin/ruby
# -*- coding: UTF-8 -*-
 
def test(a1="Ruby", a2="Perl")
   puts "编程语言为 #a1"
   puts "编程语言为 #a2"
end
test "C", "C++"
test

以上实例运行输出结果为:

编程语言为 C
编程语言为 C++
编程语言为 Ruby
编程语言为 Perl

从方法返回值
Ruby 中的每个方法默认都会返回一个值。这个返回的值是最后一个语句的值。例如:

实例

def test
   i = 100
   j = 10
   k = 0
end

在调用这个方法时,将返回最后一个声明的变量 k。

Ruby return 语句
Ruby 中的 return 语句用于从 Ruby 方法中返回一个或多个值。

语法

return [expr[`,' expr...]]

如果给出超过两个的表达式,包含这些值的数组将是返回值。如果未给出表达式,nil 将是返回值。

实例

return
 
或
 
return 12
 
或
 
return 1,2,3

看看下面的实例:

实例

#!/usr/bin/ruby
# -*- coding: UTF-8 -*-
 
def test
   i = 100
   j = 200
   k = 300
return i, j, k
end
var = test
puts var

以上实例运行输出结果为:

100
200
300

可变数量的参数
假设您声明了一个带有两个参数的方法,当您调用该方法时,您同时还需要传递两个参数。

但是,Ruby 允许您声明参数数量可变的方法。让我们看看下面的实例:

实例

#!/usr/bin/ruby
# -*- coding: UTF-8 -*-
 
def sample (*test)
   puts "参数个数为 #test.length"
   for i in 0...test.length
      puts "参数值为 #test[i]"
   end
end
sample "Zara", "6", "F"
sample "Mac", "36", "M", "MCA"

在这段代码中,您已经声明了一个方法 sample,接受一个参数 test。但是,这个参数是一个变量参数。这意味着参数可以带有不同数量的变量。以上实例运行输出结果为:

参数个数为 3
参数值为 Zara
参数值为 6
参数值为 F
参数个数为 4
参数值为 Mac
参数值为 36
参数值为 M
参数值为 MCA

类方法
当方法定义在类的外部,方法默认标记为 private。另一方面,如果方法定义在类中的,则默认标记为 public。

方法默认的可见性和 private 标记可通过模块(Module)的 public 或 private 改变。

当你想要访问类的方法时,您首先需要实例化类。然后,使用对象,您可以访问类的任何成员。

Ruby 提供了一种不用实例化即可访问方法的方式。让我们看看如何声明并访问类方法:

class Accounts
   def reading_charge
   end
   def Accounts.return_date
   end
end

我们已经知道方法 return_date 是如何声明的。它是通过在类名后跟着一个点号,点号后跟着方法名来声明的。您可以直接访问类方法,如下所示:

Accounts.return_date

如需访问该方法,您不需要创建类 Accounts 的对象。

Ruby alias 语句
这个语句用于为方法或全局变量起别名。别名不能在方法主体内定义。即使方法被重写,方法的别名也保持方法的当前定义。

为编号的全局变量($1, $2,…)起别名是被禁止的。重写内置的全局变量可能会导致严重的问题。

语法

alias 方法名 方法名
alias 全局变量 全局变量

实例

alias foo bar
alias $MATCH $&

在这里,我们已经为 bar 定义了别名为 foo,为 $& 定义了别名为 $MATCH。

Ruby undef 语句
这个语句用于取消方法定义。undef 不能出现在方法主体内。

通过使用 undef 和 alias,类的接口可以从父类独立修改,但请注意,在自身内部方法调用时,它可能会破坏程序。

undef 方法名

实例
下面的实例取消名为 bar的方法定义:

undef bar

Ruby学习-1.学习对象

本章会介绍以下内容。

  • 使用 Ruby

    了解如何使用 Ruby 编写并执行程序。

  • 使用字符和数值

    了解字符和数值是如何输出、计算以及给变量赋值等内容。

  • 使用条件判断和循环处理

    了解如何通过字符串或数值比较进行条件判断处理,以及如何进行循环处理。

读完本章,大家就能大概掌握用 Ruby 编写程序的方法了。

1.1 Ruby 的运行方法

首先,让我们用 Ruby 编写一个在屏幕上输出字符的小程序。

Ruby 程序有多种执行方法,其中最常见的方法是使用 ruby 命令来执行,其次就是使用 irb 命令,以交互式命令行方式来执行。若只是想执行小程序,使用 irb 命令会相对简单一点。

接下来,我们先介绍 ruby 命令以及 irb 命令的使用方法。

1.1.1 ruby 命令的执行方法

首先,让我们看看代码清单 1.1 的程序。

代码清单 1.1 helloruby.rb

print("Hello, Ruby.\n")

注 日文 Windows 系统中的 \ 会显示为¥。原则上,本书统一书写为 \。

各位是否有些沮丧呢?一般听到“程序”,我们可能会联想到一长串密码似的东西。但这个程序的代码只有一行,总共才 20 来个字符。可这的确是一个真真切切的程序,执行后就可以达到我们预想的目的。

请大家打开编辑器,写入上述程序,将文件名修改为 helloruby.rb,保存文件。.rb 是 Ruby 程序的后缀,表示这个文件内容是 Ruby 程序。

备注 写代码时会用到编辑器或者 IDE,它们的相关内容请参考 A.5 节。

接下来让我们启动控制台,执行程序。

备注 关于控制台的启动方法,请参考附录 A 里各操作系统的说明。

启动控制台后,使用 cd 命令,移动到存放 helloruby.rb 的文件夹中。例如,使用 Windows,文件放在 C 盘的 src 文件夹(c:\src),然后执行以下命令,

> cd c:\src

接着再执行,

> ruby helloruby.rb

执行后,如图 1.1 所示,会显示“Hello, Ruby.”。

Ruby学习-1.学习对象(1)

图 1.1 执行 Ruby


1.1.2 irb 命令的执行方法

接下来,我们介绍 irb 命令的执行方法。

与 ruby 命令一样,irb 命令在控制台执行,不过不需要指定程序文件。

执行 irb 命令后,就会出现以下这样的命令提示符。1

1使用 Ruby Instarller for Windows 安装包安装的 Ruby,在执行 irb 命令的时候有可能会显示“DL is deprecated, please use Fiddle”这样的警告。这是由于 Ruby Instarller for Windows 安装包附带的 readline 库引用了名为 DL 的旧版本的库,但这个警告不会对使用有任何影响。——译者注

执行示例

> irbirb(main):001:0>

在这里,只需把刚才代码清单 1.1 的代码原封不动地在控制台写一次,然后直接按下回车键,即可执行程序。

执行示例

irb(main):001:0> print("Hello, Ruby.\n")Hello, Ruby.  print 方法输入的结果=> nilirb(main):002:0>

备注 第三行的 nil 是 print 方法的返回值。关于方法的返回值我们将在 7.3.1 节详细说明。

像这样,在控制台写的程序可以马上在控制台里执行,这对进行简单的小测试非常方便。但是,这个方法并不适合大程序,这时我们应该考虑使用 ruby 命令。

注 在使用 Mac OS X 时,irb 命令会有无法正确输入日语的情况。这时可在 irb 命令后加上 --noreadline 选项,执行 irb --noreadline 命令。这样一来,关闭 readline 功能后,就可以正常输入日语了。但请注意,由于关闭了 readline 功能,在控制台编辑已经输入的字符、查看历史输入记录等功能都将无法使用。

在控制台输入 exit 后,按回车键,或者同时按下 Ctrl + d,都可以终止 irb 命令。

1.2 程序解说

接下来,让我们详细解说一下代码清单 1.1 的程序,虽然代码只有孤零零的一行。

1.2.1 对象

首先,请留意 "Hello, Ruby.\n" 这部分。

Ruby学习-1.学习对象(1)

这部分被称为 String 对象或者字符串对象,也可以直接称这部分为字符串。也就是说,这部分是一个代表字符串 Hello, Ruby. 的对象(图 1.2)。

Ruby学习-1.学习对象(1)

图 1.2 数据与对象

字符串、数值、时间等各种数据,在 Ruby 中都是对象。

备注 字符串末尾的 \n 是换行符。

1.2.2 方法

这一次,让我们留意一下 print 这部分。

print 是一个方法。所谓方法,就是对象的行为。数值的加法或乘法运算、字符串的合并、某时刻一小时后或者一天后的计算等操作,都是通过执行方法来实现。

print 方法的作用就是输出 () 里的内容。因此,执行 helloruby.rb 后,在控制台显示了字符串对象——Hello, Ruby.

我们把执行方法时必需的条件称为参数。例如,我们在说明 print 方法时,会说“print 方法会把作为参数传递过来的字符串,输出到控制台中”。

我们更换一下 print 方法的参数,试一下把它换成其他字符串。

print("Hello, RUBY!\n")

这一次,我们希望输出大写字母的 Hello, RUBY!。是不是感觉会更加精神点呢?

1.3 字符串

我们再详细看看有关字符串的内容。

1.3.1 换行符与 \

上文我们提到过字符 \n 是换行符。利用换行符,我们可以用普通的字符达到换行的效果,例如,为达到以下效果,

Hello,Ruby!

程序可以这么写:

原本也可以像下面一样这么写:

print("Hello, Ruby ! ")

输出结果虽然与第一种写法是一样的,但是,这样的写法会降低程序的可读性,因此并不是一个好的写法。既然 Ruby 已经帮我们准备了换行符,我们就直接用第一种方法吧。

除了 \n 以外,当我们想在字符串里嵌入特殊符号时,也会用到 \。双引号是表示字符串开始和结束的符号,假设我们希望字符串里包含双引号,程序要写成 \"

print("Hello, \"Ruby\".\n")

的输出结果为:

Hello, "Ruby".

像这样,程序会对字符串里 \ 后的字符做特殊处理。2 因此,如果字符串里需要包含 \,程序要写成 \\。例如,

2这个过程称为转义,\ 称为转义字符。——译者注

print("Hello \\ Ruby!")

的输出结果为:

Hello \ Ruby!

请注意,两个 \ 的输出结果是一个 \。

1.3.2 ' ' 与 " "

创建字符串对象除了可以使用" "(双引号)外,也可以使用' '(单引号)。我们试试把之前程序的双引号换成单引号,看一下有什么样的效果。

这次的输出结果为:

Hello, \nRuby\n!\n

程序会原封不动地输出单引号里的内容。

也就是说,在单引号里,像 \n 这样的特殊字符不经过转义,程序会原封不动地直接输出。但也有例外,例如在字符串里想嵌入 \ 与单引号时,还是需要在之前加上 \。也就是像这样,

print('Hello, \\ \'Ruby\'.')

的输出结果为:

Hello, \ 'Ruby'.


以上是关于Ruby学习笔记7.Ruby 循环及方法的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 Ruby 找到最小值/最大值

Ruby学习-1.学习对象

Ruby 学习笔记1

Ruby Programming学习笔记

Apt on WSL2 的 Ubuntu 版本不包括最新版本的 ruby​​-build

ruby学习笔记