首页 > 代码库 > Programming Ruby 阅读笔记

Programming Ruby 阅读笔记


  • 在Ruby中,通过调用构造函数(constructor)来创建对象

song1=Song.new("Ruby")

  • Ruby对单引号串处理的很少,除了极少的一些例外,键入到字符串字面量的内容就构成了这个字符串的值。

Ruby对双引号字符串游更多地处理。首先,它寻找以反斜线开始的序列,并用二进制值替换它们。其次是字符串内的表达式内插,#{表达式}序列会被“表达式”的值替换。

  • $greeting="Hello" # $greeting是全局变量
  • @name="Prodence"  # @name是实例变量
  • Ruby 使用一种命名惯例来区分名称的用途:名称的第一个字符显示这个名称如何被使用。局部变量、方法参数和方法名称都必须以小写字母或下划线开始。全局变量都有$为前缀,实例变量以@符号开始,类变量以@@符号开始。类名称、模块名称和常量必须以一个大写字母开始。
  • 许多语言中nil(或null)的概念是指“没有对象”, 在Ruby中,这是不一样的:nil是一个对象,与别的对象一样,只不过它是用来表示没有任何东西的对象。
  • a = %w{ant bee cat dog} 等价于下面的表达方式
  • a= [‘ant‘,‘bee‘, ‘cat‘ ,‘dog‘]
  • 正则表达式只是一种指定字符模式的方法,这个字符模式会在字符串中进行匹配。在Ruby中,通常在斜线之间(/pattern/)编写模式来创建正则表达式。
  • Block:

def call_block

puts "Start of method"

yield

yield

puts "End of method"

end

call_block {puts "In the block"}

 

Result:

Start of method

In the block

In the block

End of method

 

使用block来实现迭代器:迭代器是从某种收集如数组中连续返回元素的方法

animals= %w(ant bee cat dog elk)

animals.each{|animal| puts animal}

 

Result:

ant

bee

cat

dog

elk

class Song

def initialize(name, artist, duration)

@name=name

@artist=artist

@duration=duration

end

end

song=Song.new("Bicyclops","Fleck",260)

puts song.inspect

 

Result:

#<Song:0x00000002eca6d8 @name="Bicyclops", @artist="Fleck", @duration=260>

inspect方法(可以发送给任何对象)默认将对象的ID和实例变量格式化。

 

  • 一个对象的外部可见部分被称为其属性(attribute)

class KaraokeSong < Song

def initialize(name, artist, duration, lyrics)

super(name, artist,duration)

@lyrics=lyrics

end

def to_s

"KS: #{@name}--#{@artist} (#{@duration}) {#{@lyrics}}"

end

attr_reader :name, :artist, :duration, :lyrics  # Attributs setting method 2

def  name  #Attribute setting method 1

@name                

end

def artist

@artist

end

end

 

song=KaraokeSong.new("Bicyclops","Fleck",260,"And now,the...")

puts song.artist

 

  • 当调用super而不使用参数时, Ruby向当前对象的父类发送一个消息,要求它调用子类中的同名方法
  • Object的实例方法
  • 可写的属性:

方法一: 创建一个名字以等号结尾的方法

  

方法二:attr_writer

  

  • 虚拟属性 Virtual Attributes

 

上面的示例中使用属性方法创建了一个虚拟的实例变量。对外部世界来说,duration_in_minutes就像其他属性一样。然而,在内部它没有相应的实例变量。

 

  • 属性、实例变量及方法

属性就是一个方法。某些时候,属性简单地返回实例变量的值。某些时候,属性返回计算后的结果。并且某些时候,那些名字已等号结尾的方法,被用来更新对象的状态。

当设计一个类的时候,决定其具有什么样的内部状态,并决定这内部状态对外界的表现形式。内部状态保存在实例变量中。通过方法暴露出来的外部状态,我们称之为属性。类可以执行的其他动作,就是一般方法。

 

  • 类变量:类变量以两个@符开头,与全局变量和实例变量不同,类变量在使用之前必须被初始化,通常,初始化就是在类定义中的简单赋值

 

  • 类方法,不束缚于任何特定对象的方法。

new方法创建一个新的类对象,但是new方法本身并不与一个特定的对象相关联。

类方法和实例方法是通过它们的定义区别开来的: 通过在方法名之前放置类名以及一个句点,来定义类方法

 

 

  • 访问控制 Access Control
  1. Public(公有)方法可以被任何人调用,没有限制访问控制。方法默认是public的(initialize除外,它是private的)
  2. Protected(保护)方法只能被定义了该方法的类或其子类的对象所调用。整个家族均可访问
  3. Private(私有)方法不能被明确的接收者调用,其接收者只能是self。这意味着稀有方法只能在当前对象的上下文中被调用;你不能调用另一个对象的私有方法

 

 

另外,可用通过将方法名作为参数列表传入访问控制函数来设置它们的访问级别

  

  • 变量

变量是一个对象吗?在Ruby中,答案是‘不’。变量只是对象的引用。对象漂浮在某处一个很大的池中(大多数时候是堆,即heap中),并由变量指向它们

  

可以通过使用String的dup方法来避免创建别名,它会创建一个新的、具有相同内容的String对象

  

可以通过冻结一个对象来阻止其他人对其进行改动。试图更改一个被冻结的对象,Ruby将引发一个TypeError异常

  

  • 容器(Continuers):是指含有一个或多个对象引用的对象

数组类含有一组对象引用。每个对象引用占据数组中的一个位置,并由一个非负的整数索引来标识

 

数组有[]操作符来进行索引。和Ruby的大多数操作符一样,它实际上是一个方法(Array类的一个实例方法),因此可以被子类重载。使用非负整数访问数组,将会返回处于该整数位置上的对象,如果此位置上没有对象,则返回nil。使用负整数访问数组,则从数组末端开始计数

 

可以使用一对数字[start, count]来访问数组,这将返回一个包含从start还是的count个对象引用的新数组

 

还可以使用range来对数组进行索引,其开始和结束位置被两个或3个点分隔开。两个点的形式包含结束位置,而3个点的形式不包含

  

[]操作符有一个相应的[]=操作符,他可以设置数组中的元素。如果下标是单个整数,那么其位置上的元素将被赋值语句右边的东西所替换。造成的任何间隙由nil来填充

 

  

  • 散列表 Hashes

也成关联数组、图、词典。Hash可以用任何类型的对象来进行索引,比如字符串、正则表达式等等。当你将一个值存入Hash时,需要提供两个对象,一个是索引(通常称为键(key)),另一个是值。

  

  • Block

首先, block在代码中只和方法调用一起出现;block和方法调用的最后一个参数处于同一行,并紧跟在其后(或者参数列表的右括号的后面)

其次, 在遇到block的时候,并不立即执行其中的代码。Ruby会记住block出现时的上下文(局部变量、当前对象等),然后执行方法调用

在block定义中,参数列表位于两个竖线(管道符)之间, block可以有人以数量的参数

 

返回低于某个值的所有Fibonacci数列项:

 

如果传递给block的参数是已经存在的局部变量,那么这些变量即为block的参数,它们的值可能会因block的执行而改变。同样的规则适用于block内的变量:如果它们第一次出现在block内,那么它们就是block的局部变量。相反,如果它们先出现在block外,那么block就与其外部环境共享这些变量

Defined? 方法在其参数没有定义时返回nil

  

inject迭代器:让你可以遍历收集的所有成员以累计出一个值

inject是这样工作的:block第一次被执行时,sum被置为inject的参数,而element被置为收集的第一个元素。接下来每次执行block时,sum被置为上次block被调用时的返回值。inject的最后一次调用block返回的值。如果inject没有参数,那么它使用收集的第一个元素作为初始值,并从第二个元素开始迭代。

  

  • 闭包(closure)

  

  • 数字

一定范围内的整数

 

在内部以二进制形式存储,它们是Fixnum类的对象,范围之外的整数存储在Bignum类的对象

Ruby 会自动管理它们之间的来回转换。

  

在书写整数时,可以使用一个可选的前导符号,可选的进制指示符(0表示八进制,0d表示十进制[默认], 0x表示十六进制或者0b表示二进制),后面跟一串符合适当进制的数字。下划线在数字串中被忽视。

 

所有整数都是对象,并且可以对各种形式的消息作出响应。Ruby使用num.abs而不是abs(num)去得到数字的绝对值

整数支持的几种有用的迭代器:

  

注意downcase方法名称结尾处的感叹号, 这个标识用来表示方法会在适当的位置修改接收者,在这个例子中,它把字符串变成小写

  

  • 区间

1. 区间的第一个且最可能最自然的用法是:表达序列。在Ruby中,使用“..”和“...”区间操作符来创建序列。两个点的形式是创建闭合的区间(包括右端的值),而3个点的形式是创建半闭半开的区间,不包括右端的值

<=>太空船操作符,它比较两个值,并根据第一个值是否小于、等于、大于第二个值,分别返回-1,0,+1

2. 区间作为条件:在这里它们表现的就像某种双向开关 - 当区间第一部分的条件为为true时,它们就打开,当期间第二部分的条件为true时,它们就关闭。例如下面的代码段,打印从标准输入得到的行的集合,每组的第一行包含start这个词,最后一行包含end这个词

3. 区间作为间隔: 看看一些值是否会落入区间表达的间隔内。使用===(case equality操作符)可以做到这一点

 

Programming Ruby 阅读笔记