• Home
  • About
    • Road to Coding photo

      Road to Coding

      只要那一抹笑容尚存, 我便心无旁骛

    • Learn More
    • Email
    • Github
  • Posts
    • All Posts
    • All Tags

Ruby学习笔记(二)

06 Feb 2018

之前一直不清楚OOP,对OOP最深的印象就是,所有的函数直接” . “进行调用

那么,今天就来看看所谓的”函数”,即方法的相关内容

一 方法

什么是方法?

由对象定义的与对象有关的操作,Ruby中将对对象的操作封装成为方法

从smartalk沿承下来的一个概念:发送消息

将对象作为消息的接收者,通过调用方法的形式,将消息(方法)发送给对象,

把参数和消息一起发送给对象的过程,叫方法的调用

切记: Ruby中方法的调用,可以省略括号,(必要时刻避免不必要的理解错误)

<1> 方法的调用

分为以下三种:

  1. 简单方法的调用

  2. 带块方法的调用

  3. 运算符形式的方法调用

此处仅为了解,之后会详解三种方法调用

注意:

1. 带块的方法,像之前说的,do ~ end 与 { ~ }可以替换,但是,do ~ end可以省略参数列表的括号

反之,{ ~ }只有在没有参数时,才可以省略括号,有一个以上都不能省略括号

2. 运算符形式的方法可以重定义,有的可以,有的则不行

<2> 方法的分类

方法同时也可以根据接收对象来进行分类:

  1. 实例方法

  2. 类方法

  3. 函数式方法

实例方法: 就像表面含义一样,是给类的实例对象进行调用的方法,就是常见的函数调用

类方法: 给类进行使用的方法

例如,我们常见的创建对象的方法,就是类方法

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时:

  1. reutrn的值即为返回值,且立刻返回

  2. return后无从参数,则返回 nil 例如print返回值就为nil

无return时

  1. 方法的最后一个表达式,即为返回值

  2. 上一条规则不一定正确,程序流结束处为返回值,

<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



Ruby Share Tweet +1