Ruby中的方法和其它编程语言中的函数类似,主要是用于捆绑一个或多个重复的语句到一个单元中,其命名应以小写字母开头,如果以大写字母开头的话,可能会被系统认为是常量,同时呢,方法应在调用之前定义,否则 Ruby 会产生未定义的方法调用异常,咱们来看下方法的定义:

#普通定义
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

Ruby 中的每个方法默认都会返回一个值。这个返回的值是最后一个语句的值,来看一个方法:

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

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

Ruby 方法中有一个return语句用来返回一个或者多个值,如果给出超过两个的表达式,包含这些值的数组将是返回值。如果未给出表达式,nil 将是返回值。来看一个实例:

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

假如我们声明了一个带有两个参数的方法,当我们调用时,还需要传递两个参数,这时,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。但是,这个参数是一个变量参数。这意味着参数可以带有不同数量的变量。

当方法定义在类的外部,它默认标记为private,在类中则标记为public,它默认的可见性和 private 标记可通过模块(Module)的 publicprivate 改变,当我们想要访问类的方法时,我们首先需要实例化类,之后使用对象就可以访问类的任何成员,并且Ruby 提供了一种不用实例化即可访问方法的方式,我们来看下声明并访问类方法的实例:

class Accounts
   def reading_charge
   end
   def Accounts.return_date
   end
end

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

Accounts.return_date

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

再来看下alias语句,它用于为方法或全局变量起别名。别名不能在方法主体内定义。即使方法被重写,方法的别名也保持方法的当前定义。为编号的全局变量($1, $2,...)起别名是被禁止的。重写内置的全局变量可能会导致严重的问题,来看下语法格式:

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

实例如下:

alias foo bar
alias $MATCH $&

上述代码中,我们已经为 bar 定义了别名为 foo,为 $& 定义了别名为 $MATCH。

还有就是undef语句,它用于取消方法定义,并且不能出现在方法主体内,我们通过使用 undefalias,类的接口可以从父类独立修改,但请注意,在自身内部方法调用时,它可能会破坏程序,来看实例:

#语法
#undef 方法名
#取消名为 bar的方法定义实例
undef bar

上面介绍完了之后,我们就来看下块的概念:

  • 块由大量的代码组成。
  • 需要给块取个名称。
  • 块中的代码总是包含在大括号 {} 内。
  • 块总是从与其具有相同名称的函数调用。这意味着如果块名称为 test,那么要使用函数 test 来调用这个块。
  • 可以使用 yield 语句来调用块。

语法如下:

block_name{
   statement1
   statement2
   ..........
}

我们先来看看一个 yield 语句的实例:

#!/usr/bin/ruby
# -*- coding: UTF-8 -*-
 
def test
   puts "在 test 方法内"
   yield
   puts "你又回到了 test 方法内"
   yield
end
test {puts "你在块内"}

我们也可以传递带有参数的 yield 语句,来看实例:

#!/usr/bin/ruby
# -*- coding: UTF-8 -*-
 
def test
   yield 5
   puts "在 test 方法内"
   yield 100
end
test {|i| puts "你在块 #{i} 内"}

上述代码中,yield 语句后跟着参数,我们甚至可以传递多个参数。在块中,我们可以在两个竖线之间放置一个变量来接受参数。因此,在上面的代码中,yield 5 语句向 test 块传递值 5 作为参数。

我们来看下面的语句:

test {|i| puts "你在块 #{i} 内"}

上述代码中,值 5 会在变量 i 中收到。现在,我们来观察下面的 puts 语句:

puts "你在块 #{i} 内"

上述代码输出的就是“你在块5 内”,如果我们想要传递多个参数,那么 yield 语句如下所示:

yield a, b

此时呢,块如下所示:

test {|a, b| statement}

参数我们就用逗号分隔啊。

我们通常使用 yield 语句从与其具有相同名称的方法调用块,实例如下:

#!/usr/bin/ruby
 
def test
  yield
end
test{ puts "Hello world"}

上述代码是实现块的最简单的方式,但是如果方法的最后一个参数前带有 &,那么我们可以向该方法传递一个块,且这个块可被赋给最后一个参数,如果 * 和 & 同时出现在参数列表中,& 应放在后面,来看实例:

#!/usr/bin/ruby
 
def test(&block)
   block.call
end
test { puts "Hello World!"}

每个 Ruby 源文件可以声明当文件被加载时要运行的代码块(BEGIN 块),以及程序完成执行后要运行的代码块(END 块),并且一个程序可以包含多个 BEGIN 和 END 块。BEGIN 块按照它们出现的顺序执行。END 块按照它们出现的相反顺序执行,我们来看下实例:

#!/usr/bin/ruby
 
BEGIN { 
  # BEGIN 代码块
  puts "BEGIN 代码块"
} 
 
END { 
  # END 代码块
  puts "END 代码块"
}
  # MAIN 代码块
puts "MAIN 代码块"

好啦,本次记录就到这里了。