之前一直不清楚OOP,对OOP最深的印象就是,所有的函数直接” . “进行调用
那么,今天就来看看所谓的”函数”,即方法的相关内容
一 方法
什么是方法?
由对象定义的与对象有关的操作,Ruby中将对对象的操作封装成为方法
从smartalk沿承下来的一个概念:发送消息
将对象作为消息的接收者,通过调用方法的形式,将消息(方法)发送给对象,
把参数和消息一起发送给对象的过程,叫方法的调用
切记: Ruby中方法的调用,可以省略括号,(必要时刻避免不必要的理解错误)
<1> 方法的调用
分为以下三种:
-
简单方法的调用
-
带块方法的调用
-
运算符形式的方法调用
此处仅为了解,之后会详解三种方法调用
注意:
1. 带块的方法,像之前说的,do ~ end 与 { ~ }可以替换,但是,do ~ end可以省略参数列表的括号
反之,{ ~ }只有在没有参数时,才可以省略括号,有一个以上都不能省略括号
2. 运算符形式的方法可以重定义,有的可以,有的则不行
<2> 方法的分类
方法同时也可以根据接收对象来进行分类:
-
实例方法
-
类方法
-
函数式方法
实例方法: 就像表面含义一样,是给类的实例对象进行调用的方法,就是常见的函数调用
类方法: 给类进行使用的方法
例如,我们常见的创建对象的方法,就是类方法
Array.new
File.open(filename)
同时,不直接对实例操作,而是通过所属的类进行属性的改变时,也使用类方法
File.rename(old_name, new_name)
#实例方法:
filename = ARGV[0]
# file = File.open(filename)
text = file.read
file.close
#类方法:
text = File.read(filename)
同时,切记,类方法也可以这样调用 “::”,省得以后概念看不懂
text = File::read(filename)
函数式方法: 没有接受者的方法即为函数式方法,(其实到后面就知道,接受者是self)
叫函数式方法,是因为此类方法不关心接受者是谁,反过来,就是没有接收者的方法为函数式方法
另外解释一个情况: Array#new, 这是Ruby文档中对方法名的标记形式
二 方法的定义
上面说了这么多,也该说说方法的定义了
<1> 方法的定义
def 方法名(参数列表)
进行的处理
end
方法名可有下划线,字母,数字组成,不能以数字开头
下面看几个例子:
def hello(name)
puts "my name is #{name}"
end
def hello(name = "ruby") # 指定无参数时的默认值
pust "my name is #{name}"
end
带块的方法,类方法,会在介绍了类之后进行接受到介绍
<2> 方法的返回值
下面有几条方法返回值的规则:
有return时:
-
reutrn的值即为返回值,且立刻返回
-
return后无从参数,则返回 nil 例如print返回值就为nil
无return时
-
方法的最后一个表达式,即为返回值
-
上一条规则不一定正确,程序流结束处为返回值,
<3> 参数个数不确定时
在C中,实现可变从参数,使用的便是< stdarg.h >中的宏,Ruby就没这么复杂了
在参数列表中,*var(变量名),则方法会把所有的参数封装为数组,
def math(arg, *args)
[arg, args]
end
p math(1,2,3,4) #=> [1, [2, 3, 4]]
切记: 每个方法的参数列表中,不定参数列表,只能出现出现一次! ! !
类似于多重赋值的用法
<4> 关键字参数
之前,提到了,Ruby方法中需要参数按顺序指定类型值进行调用
所以,有了关键字参数的用法(ruby2.0的新特性)
关键字参数: 将变量名与变量值,成对的传进方法中
def method_name(arg1: value1, arg2: value2, ...)
do_something
end
关键字从参数的好处: 参数可以不按照默认顺序调用, 而且可以省略其中的任意参数
但是,将未定义的参数名传给方法时,会报错
因为上面提到了,未定义的参数名,所以我们有一个处理未定义参数名的方法: **args参数
在方法定义中,使用此参数,用于回收未定义的参数名以及变量值,并以hash的形式保存
def meth(x: 1, y: 2, **args)
[x, y, args]
end
p meth(x: 5, y: 9, z: 0) #=> [5, 9, {:z=>0}]
同时,可以直接将hash作为参数传递,会使用与关键字参数匹配的方法进行参数,变量名的核对
因为,关键字参数的实现,就是参考传递hash作为参数而来的
最后,建议大家,多多使用关键字参数,很方便
<5> 小技巧
1. 将数组作为参数传递
之前,看到过,hash作为参数,我们也使用了,*args的形式,进行不定参数的封装
所以,我们可以使用*args的形式,将数组作为参数传递
def foo(x, y, z)
x + y + z
end
a = [2, 3]
foo(1, *a)
但是,数组与参数列表的数目一定要核实,相等
区分: *args的不同用法
在方法调用时,*args,表示将数组中的参数一一传递
方法定义时,*args,表示接收不定参数
三 聊聊Ruby的格式
<1> 换行
Ruby中以一行结束作为语句结束的标识
它也可以使用 ; 作为结束的标识
一般不建议用; ,用一行结束来表示语句的结束,简洁明了
<2> 缩进
Ruby也有缩进,但是,使用的是软缩进(2个空格的Tab)
同时,搭配上do ~ end使得程序结构清晰明了
<3> 空白
Ruby中针对于空白要求比较严格
不能乱空白
a + b O
a+b O
a +b X
a+ b X
上面第三种写法的问题很严重,意思时,调用名为+,参为b的方法 !!!
最后,要想写出好看,优雅的代码,离不开参考别人的代码,推荐Rails的学习!
(当然,我离那一步还有点距离)
方法很重要,定义了对象的行为,下一篇的类与模块,可以说是Ruby的精华之一了
February 6, 2018 2:58 PM