Stonefishy Blog - by Andrew Shi

Scribbles of a front and back ends developer

Ruby修炼之道(5)

方法

在Ruby中,调用方法时是可以省略()的

1
2
>> print("Hello world")             #=>Hello world
>> print "Hello world"             #=>Hello world

带块的方法 带块的方法如time,each方法,其语法如下:

对象.方法名(参数,...) do |变量1,...|
    块内容
end

Ruby中方法可归为3类:

实例方法 即由对象来调用,以下数组的size方法为实例方法

1
>> [1, 2].size                      #=>size方法即为实例方法

类方法 由类本身来调用,和C#、Java中得静态方法类似,类方法不属于任何一个对象

1
2
3
>> Array.new
>> File.open("some_file")
>> Time.now

调用类方法时,可以使用::代替.

函数式方法

1
2
>> print "hello"
>> sleep(10)

在Ruby的帮助文档中,一般使用类名#方法名来标记实例方法,用类名.方法名或者类名::方法名来标记类方法

方法的定义

定义方法的语句如下:

def 方法名(参数1,参数2,...)
    希望执行的处理
end

可以指定默认参数给方法,当方法有多个参数时,从参数列表的右边开始依次指定默认值

1
2
3
def func(a, b = 1, c = 2)
  #some codes
end

注,只省略左边的参数或中间的某个参数是不行的

方法的返回值使用return关键字,当这个关键字省略时,方法的最后一个表达式的结果就会成为方法的返回值。

定义带块的方法 在定义带块的方法时,需要使用yield关键字来定义块所在的位置。如下代码所示

1
2
3
4
5
6
7
8
9
#定义
def func
  yield
end

#调用
func do
  print "hello world"
end

如果yield部分有参数,程序就会将其当作块变量传到块里。快里面最后的表达式的值即为快得执行结果,同时也可以作为yield的返回值在块的外部使用。

参数个数不确定的方法 通过使用*变量名的形式来定义参数个数不确定的方法。Ruby会把所有的参数封装为数组,提供方法内部使用。

1
2
3
4
5
def func(*args)
  args
end

p func(1, 2, 3)                #=> [1, 2, 3]

当方法需要指定特定的参数,而其他参数又不确定的情况下

1
2
3
4
5
6
7
8
9
def sum(arg1, arg2, *args)
  result = arg1 + arg2
  args.each do | arg |
      result += arg
  end
  result
end

p sum(1, 2, 3, 4)           #=> 10

所有不确定的参数都被作为数组赋值给变量args, *变量名这种形式的参数,只能在方法定义的参数列表中出现一次。

关键字参数 使用关键字参数,可以将参数名与参数值成对地传给方法内部使用,这时,调用方法的参数个数以及调用顺序就可以打乱。

def 方法名(参数1:值1, 参数2:值2, ...)
    逻辑处理
end

而且还可以在方法定义时指定参数默认值

1
2
3
4
5
6
7
def sum(a: 0, b: 0)
  a + b
end

p sum(a: 10, b: 20)         #=> 30
p sum(b: 20, a: 10)         #=> 30  改变参数的调用顺序
p sum(b: 20)                  #=> 20 省略了参数a,a默认值为0

使用关键字参数定义方法,如果我们传入了未定义的参数,那么程序将会报错。如何避免呢,在Ruby中可以使用**变量名的形式来接收未定义的参数。此时,Ruby会把参数列表以外的其他关键字参数以散列对象的形式保存。

1
2
3
4
5
6
7
8
9
def   sum(a: 0, b: 0, **args)
  result = a + b
  args.each do |key, value|            #=> 遍历散列
      result += value
  end
  result
end

sum(a: 1, b: 2, c: 3, d: 4)         #=> 10

当然,关键字参数也可以与普通参数一起搭配使用。

1
2
3
4
5
def sum(a, b: 1, c: 2)
  sum = a + b + c
end

sum(10, b: 20, c: 30)            #=> 60

以关键字参数定义的方法,Ruby会自动将其封装为散列然后传递给方法内部,所以基于此,我们当然也可以利用散列的键值来将散列传递给方法

1
2
3
4
5
6
7
8
def sum(a: 0, b: 0, c: 0)
  sum = a + b + c
end

args = {a: 1, b: 2, c: 3}          #=> 定义散列args
sum(args)                             #=> 6 将散列args传递给sum方法
sum({"a"=>1, "b"=>2, "c"=>3}       #=> 6 将散列直接传给方法
sum(c: 3, a: 1, b: 2)             #=> 6 可省略{}

使用关键字参数定义方法,既可以对键进行限制,又可以定义参数的默认值,建议在实际编程中多尝试使用关键字参数