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)的 public 或 private 改变,当我们想要访问类的方法时,我们首先需要实例化类,之后使用对象就可以访问类的任何成员,并且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语句,它用于取消方法定义,并且不能出现在方法主体内,我们通过使用 undef 和 alias,类的接口可以从父类独立修改,但请注意,在自身内部方法调用时,它可能会破坏程序,来看实例:
#语法
#undef 方法名
#取消名为 bar的方法定义实例
undef bar
上面介绍完了之后,我们就来看下块的概念:
语法如下:
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 代码块"
好啦,本次记录就到这里了。