Ruby 内置类的学习笔记

作者:袖梨 2022-06-25

Ruby 的字面构造器

Ruby 大部分的内置类可以使用 new 来实例化:

str = String.new
arr = Array.new
有些类不能使用 new 来实例化,比如 Integer 类。有些内置类可以使用字面构造器,就是不需要使用 new ,可以使用一种特别的形式来创建类的实例。

内置类的字面构造器

String:使用引号, —— "new string",'new string'
Symbol:冒号在前,—— :symbol,:"symbol with spaces"
Array:方括号,—— [1,2,3]
Hash:大括号,—— {"New York" => "NY", "Oregon" => "OR"}
Range:两个或三个点,—— 0..9 或者 0...10
Regexp:斜线,—— /([a-z]+)/
Proc(Lambda):横线,箭头,括号,大括号 —— ->(x,y){x * y}
糖衣语法

语法糖(Syntactic Sugar)。方法调用是这个形式:object.method(args),但 Ruby 提供了一些糖衣语法,可以让方法调用更漂亮:

x = 1 + 2
上面相当于是:

x = 1.+(2)
通过定义方法来定义操作符

如果在类里定义了 a + 方法,你的类的对象就可以使用加法的糖衣语法。注意,操作符也是一种方法,这种方法只是作为操作符来用,让它更好看点。

使用 + 是一种惯例,Ruby 本身不知道 + 的意思是加法。你可以定义自己的不是加法的 + 方法:

obj = Object.new
def obj.+(other_obj)
"想加点东西吗?"
end
puts obj + 100
puts 后面的 + 是调用 obj 上面的 + 方法,整数 100 是它的唯一参数。实际上 obj 上的 + 方法不是加法的意思,而只是简单的输出一个字符串。

在操作符糖衣之上的是快捷糖衣:x += 1 就是 x = x + 1。下面的银行账号类里有 + 与 - 方法:

class Account
attr_accessor :balance

def initialize(amount=0)
self.balance = amount
end

def +(x)
self.balance += x
end

def -(x)
self.balance -= x
end

def to_s
balance.to_s
end
end

acc = Account.new(20)
acc -= 5
puts acc
上面输出的结果是 15。定义了 - 这个实例方法以后,我们就可以使用 -= 这个快捷方式了。

自定义一元操作符

+ 与 - 是一元操作符,在自己的类或对象里你可以指定 +obj 与 -obj 这些表达式的行为,可以定义方法 +@ 与 -@ 。

比如你想在一个叫 Banner 的类里面重新定义 + 与 - 的行为,让它们意思是把字符串变成大写字母或小写字母:

class Banner
def initialize(text)
@text = text
end

def to_s
@text
end

def +@
@text.upcase
end

def -@
@text.downcase
end
end
然后再实验一下:

banner = Banner.new("Eat at David's!")
puts banner # 输出:Eat at David's!
puts +banner # 输出:EAT AT DAVID'S!
puts -banner # 输出:eat at david's!
下午 5:30 ***

下午7:22 **

你也可以定义 ! 操作符,定义一个 ! 方法就行了,完成以后你会有一个一元操作符 ! ,另外还有一个 not :

class Banner
def !
reverse
end
end
再实验一下:

puts !banner # 输出:!s'divaD ta taE
puts (not banner) # 输出:!s'divaD ta taE
! 方法

2016年9月11日 上午9:41 ***

Ruby 的方法可以使用 ! 号结尾,表示 “危险”。比如两个方法做的事情差不多,其中的一个会有点副作用,也可以说它有点危险,那么你可以让这两个方法叫一个名字,但是那个有副作用的或者有点危险的方法的名字的最后可以加上一个 ! 号结尾,比如(upcase 与 upcase!)。

这是 Ruby 的习俗,或者叫惯例,! 号本身在 Ruby 内部并没有特别的意思。但是按照惯例,有叹号的方法就表示它是一个危险的方法。什么是危险,其实是写这个方法的人定义的。比如在 Ruby 内置的类里面,带 ! 号的方法相比它的不带叹号的版本,可能会改变它的接收者。不过也不一直是这样,像:exit/exit!,sub/sub! 。

你也可以把危险想成是一种警告,或者注意! 大部分带叹号的方法都会有一个不带吧号的版本,它们是成对出现的。

破坏性

Ruby 核心带的一些带 ! 号结尾的方法有破坏性,就是它们会改变调用它的那个对象。比如 upcase 这个方法,它会返回一个新的大写字母的字母串,但是 upcase! 方法会直接改变原始的字符串。

做个实验:

>> str = 'hello'
=> "hello"
>> str.upcase
=> "HELLO"
>> str
=> "hello"
>> str.upcase!
=> "HELLO"
>> str
=> "HELLO"
Ruby 核心里的有很多这样的方法,比如 sort/sort!,strip/strip!,reverse/reverse! 。不带叹号的方法返回新的对象,带叹号的方法直接改变原始对象。你得注意调用的方法是不是会改变它的接收者。返回新的对象的方法比修改原始对象的方法更消耗资源。

另一面,你也要注意一下,修改原始对象可能会影响到程序里的其它的地方,比如可能还有些地方要使用原始的没有被修改的对象。

破坏与危险

破坏与危险并不是一回事,有些带破坏性的方法可能不带 ! 号。Ruby 本身并不在乎方法里是不是有 ! 号,只要是方法它都会被执行。这个 ! 号是方法的作者与用户之间的一种沟通的方式。这是一种惯例,有经验的人一看就知道它的意思。

想使用带 ! 号的方法,方法一定得有一个跟它对应的不带 ! 号的版本。这两个方法做的事情基本一样,就是带 ! 号的方法可能有点副作用,比如返回一个不同的值,或者有一些其它的跟不带 ! 号的方法不同的行为。

不要你觉得方法在某些方面有点危险就在方法的名字里使用 ! 号。因为任何的方法它自己本身都不是危险的。只有在一些相对的情况下,一个方法有两个名字,一个带叹号,一个不带叹号,带叹号的方法的意思是这个方法可能会有一些副作用。

比如一个保存文件的方法,别因为它能把文件保存到磁盘上,你就叫它 save! ,就叫它 save 就行了。除非你需要另一个方法,保存文件的时候不备份原始文件(假设 save 方法能备份原始文件),你可以叫这个方法 save! 。

注意并不是所有的有破坏性的方法都是用 ! 号结尾的。没人强制在方法的名字里使用 ! 号,这只是一种惯例。

to_*

上午11:54 ***

Ruby 里面有一些用 to_ 开头的方法,它们可以转换对象。比如 to_s(转换成字符串),to_sym(转换成符号),to_a(转换数组),to_i(转换整数),to_f(转换浮点小数)。

to_s:转换字符串

做个实验:

>> "hello".to_s
=> "hello"
再试一下:

>> ["one", "two", "three", 4, 5, 6].to_s
=> "["one", "two", "three", 4, 5, 6]"
再试试:

>> Object.new.to_s
=> "#<0x007fbde88267e0>


<0x007fbde882d9a0>

<0x007fbde882d9a0>











<0x007fbde8963e78>


<0x007fbde8960ed0>








































































<0x007fbde8a498d8>












<0x007fbde89fa2b0>










































































<0x007fbde89294a8>

<0x007fbde89099c8>










































<0x007fbde8960778>

<0x007fbde8959928>











































相关文章

精彩推荐