分享 Ruby 学习笔记

monsterooo · 2019年01月18日 · 最后由 xiaohh 回复于 2019年02月26日 · 2476 次阅读

Ruby 常用知识记录

语法

* ||= 或者等于运算符

* **= 产生一个 2 次方

* &= “与”位算符

* |= “或”位运算

* ^= “异或”位运算

* %= 模运算

* &&= 与等运算 (极少使用)

Object.ancestors # Object 类的祖先

self.class 指向类对象

方法记录

BasicObject.method_missing # 当对象不能相应消息时会调用此方法

Kernel.private_instance_methods.sort # 查看 Kernel 提供的所有私有实例方法

String.methods # 继承和单例方法 (实例方法和单例方法)

Obj.singleton_methods # 只能查看对象的单例方法

String.instance_methods # 查看对象拥有的所有实例方法

Obj.methods.include?(:concat) # 查看对象是否拥有某方法

String.instance_methods(false).sort # 查看类不包含祖先的实例方法的集合

String.private_methods # 查看所有私有方法

String.public_methods # 查看所有公有方法

String.protected_methods # 查看所有保护方法

类和模块

MyClass.private_instance_methods # 私有方法

MyClass.protected_instance_methods # 保护方法

MyClass.public_instance_methods # 公有方法

public_instance_methods 等于 instance_methods

Obj.respond_to?(:to_ary) # Obj 对象是否可以相应:to_ary方法

方法

具名参数,可以指定参数的名称

def m(a:, b:)
    p a, b
end
m(a: 1, b: 2) # 1, 2

内置 to_* 方法

* to_s 转换为字符串

* to_a 转换为数组,它会自动与*运算符捆绑

* to_i 字符串到整型

* to_f 字符串到浮点型

* to_str 当一个对象可以相应to_str方法,那么当对象呗用作 String#+ 的参数时,它自己的to_str的表现形式将会启用

* to_ary 对象如果有to_ary方法它就可以伪装成一个数组,一旦对象在仅作为数组的地方使用,to_ary将会被调用

常用语/法糖

x = 1 + 2
x = 1.+ 2
my_object + my_other_object
# 只要有+方法自动也获得 x += 2 语法糖方法

自定义一元运算符

通过定义+@-@可以定义一元运算符

class Banner
    def +@
        # code
    end
    def -@
        # code
    end
end
banner = Banner.new
puts +banner
puts -banner

也可以定义!方法来定义!(逻辑否定) 运算符,但是他会影响一元运算符!not。代表着!not会执行到定义的!的方法

分离数组

array = ['123', '456']
(a, b) = array # a = '123' b = '456'

bang(!) 方法和”危险”

方法以!结尾的称谓 bang 方法。这样的方法被标记为有”危险”的方法。

字符串引用机制

除了传统的字符串引用之外,还有另外一种引用格式为:%char{text}方式,char是一个特殊字符。

* %q{abc} # 同单引号

* %Q{ab#{var}c} # 同双引号

* %{ab#{var}c} # 同双引号

* %限定符号可以使用任意字符,只要两边能够匹配即可。还有限定符不能由字母组成

here 文档

如果要进入 here-doc 使用<<运算符即可,分割字符串可以是任何字符。这里结尾的EOM必须是左对齐。如下所示:

text = <<EOM
这是一段文本
EOM # 这里的EOM必须是左对齐

可以在<<后使用-连字符关闭结尾必须左对齐模式

text = <<-EOM
这是一段文本
    EOM # 这里的EOM可以不左对齐

默认情况 here-doc 使用双引号限定 (可以使用插值支字符串),如果想要使用单引号限定可以在开始的EOM使用单引号包裹起来

n = 1
text = <<'EOM'
文本 #{n}
EOM
p text # => "文本 \#{n}\n"

<<EOM作为占位符服务于即将出现的 here 文档。理解为<<EOM之后的字符串将会替换为<<EOM所在的占位符。然后在<<EOM之后还是可以接方法调用,示例如下:

a = <<EOM.to_i
5
EOM
p a # => 5

通过上面对占位符的理解我们可以在字面对象构造中使用 here 文档,示例如下:

array = [1,2,3,<<EOM,4]
这是here-doc!
EOM
p array # => [1, 2, 3, "这是here-doc!\n", 4]

# 还可以作为方法参数,如下所示
def do_something(a, b, c)
p c
end
do_something('a', 'b', <<EOM)
我是第三个参数
EOM

字符串基本操作

string[],[] 是一个方法调用

* string[1]

* string[-1]

* string[1..5]

* string[-12..-3]

* string[‘search text’] # 搜索字符串,有返回搜索字符串,无返回 nil

* string[/abc/] # 正则搜索

*

符号

符号常用的创建方式:

* :abc

* :”abc”

* “abc”.to_sym

* “abc”.intern

符号主要特点:

* 不变型:符号一旦创建不能修改。不能::abc << :d

* 唯一性:不论在合适 :abc都是同一个对象 符号主要用途:

* 作为方法参数:

* 如类对象方法 attr_accessor :name

* 消息发送 “abc”.send(:upcase)

* 作为散列键:

ruby # 符号键 hash = { :name => ‘monsterooo’ } hash[:name] # 符号键可以简写 hash = { name: ‘monsterooo’ } hash[:name] # 字符串键 hash = { ‘name’ => ‘monsterooo’ } hash[‘name’]

数值对象

日期和时间

日期和时间通过这 3 个类来操作:TimeDateDateTime

# 提供Date和DateTime类
require 'date'
# 增强Time类
require 'time'

日期常用操作:

* Date.today #

* Date.today.to_s # 2019-01-19

* Date.new(1999, 1, 1) # 传递年、月、日创建对象

* Date.parse(‘2008/8/8’) # 通过字符串构造

时间对象常用操作

* Time.new # 表示当前时间对象

* Time.now # 和Time.new相同

* Time.at(100000000) # 返回从新时代 (格林威治标准时间) 的时间点,加上以秒为单位的参数后构建时间对象

* Time.mktime(2018, 8, 8, 1, 2, 3) # 使用合理的默认值填充时间,月、日填充 1,小时、分钟、秒填充 0

* Time.parse('March 22, 1985, 10:32 PM') # 先require ‘time’,解析成时间

日期/时间对象

DateTime 是 Date 的子集,由于重载的关系,它的参数有一点不同

* DateTime.new(2019, 1, 2, 3, 4, 5) # 指定时间创建日期时间对象

* DateTime.now # 构造当前日期时间对象

* DateTime.parse # 解析日期时间 日期和时间对象提供了很多有用的方法,如下所示:

* dt = DateTime.now

* dt.year # 2019

* dt.hour # 2

* dt.minute # 26

* dt.second # 36 注意:Time 对象是t.secTime 对象并没有second方法

* dt.monday? # 判断是否为一周的某一天

* dt.leap? # 是否为闰年

日期时间格式化方法

所有的日期时间对象都有strftime方法,可以用来更灵活的格式化时间。格式化字符如下所示:

数组

新建数组方法:

* Array.new

a = Array.new

Array.new(3) # [nil, nil, nil]

Array.new(3, ‘abc’) # [‘’abc, ‘abc’, ‘abc’]

Array.new(3) { n += 1; n * 10 } # [10, 20, 30]

* []

* Array 顶层方法

接收一个参数,如果参数对象拥有to_ary方法,Array 则会调用该对象的这个方法来生成一个数组。如果to_ary不存在会尝试调用to_a方法。如果to_a方法不存在 Array 会将该对象包装到数组中然后返回它:

ruby string = 'A string' p string.respond_to?(:to_ary) # false p Array(string) # ["A string"] def string.to_a split(//) end p Array(string) # string能相应to_ary方法 ["A", " ", "s", "t", "r", "i", "n", "g"]

* %W{}%i{}符号

%W{}%w{}都会使用空格分割符号里面的字符串,不同的是%W{}可以使用字符串插值 (双引号字符串),而%w{}是单引号字符串。他们都会创建一个数组字符串

%I{}%i{}类似,只是他们创建的是符号数组

数组转换方法

obj = Object.new
Array.try_convert(obj) # nil
def obj.to_ary
    [1, 2, 3]
end
Array.try_convert(obj) # [1, 2, 3]

数组方法

* arr.unshift(‘monster’) # 数组开头添加一个元素

* arr.push(‘monster’) # 数组末尾添加一个元素 (一次性可加多个)

* arr << ‘monster’ # 数组末尾添加一个元素 (只能加一个)

* arr.shift() # 数组开端移除一个元素

* arr.pop # 数组尾端移除一个元素

* arr.concat(arr2) # 合并两个数组,arr 数组会被改变

* arr.replace(arr2) # 将数组 arr 替换为数组 arr2

* [1,2,[3,4]].flatten # 将数组扁平化为:[1, 2, 3, 4]

* [1,2,3].reverse # 将数组反制为:[3, 2, 1]

* [1,2,3].join(',') # 将数组串联起来,参数是数组之间分隔符

* [1,2,'a'] * '-' # 同上串联数组 "1-2-a"

* [1,2,3,2,1].uniq # 去重

* [1,nil,3].compact # 去除数组中包含 nil 的元素

* arr.size # 获取长度同arr.length

* a.empty? # 如果不包含任何元素返回 true,否则返回 false

* a.include?(item) # 数组是否包含指定的元素

* a.count(item) # item 在数组出现的次数

* a.first(n = 1) # 数组中第前 n 个元素

* a.last(n = 1) # 数组中末尾 n 个元素

* a.sample(n = 1) # 返回数组中任意的 n 个元素 (随机)

散列

创建散列的方式:

* {} * h = {}

* Hash.new * h = Hash.new # 创建空的 hash 对象

* Hash.[] * Hash['a','b'] # {"a"=>"b"}

* Hash 顶层方法

* Hash([]) # 传递 [] 返回空的 hash{}

* Hash(nil) # 同上返回空的 hash{}

* 如果传递对象,则会调用对象的to_hash方法

ruby a = 'abc' def a.to_hash return {value: self} end p Hash(a) # {:value=>"abc"}

添加键值对到散列

添加键值对和数组使用相同的技术:[]=加语法糖形式,要添加一个状态到 state_hahs,可以使用state_hash[’name’] = ‘monster’它是state_hash.[] = (‘name’, ‘monster’)的语法糖形式。也可以使用store来执行相同操作。state_hash.store('name', 'monster’)

从散列取值

* state_hash[‘name’]

* state_hash.fetch(‘name’)

* state_hash.values_at(‘val1’, ‘val2’) # 取多个值

指定默认的散列值和行为

* 默认情况下不存在的散列返回的是nil

h = Hash.new

h[’no such key’] # nil

* 可以给Hash.new的参数指定不同的默认值

h = Hash.new(0)

h[‘no such key’] # 0

* 定义获取不存在键的行为

h = Hash.new { |hash, key| hash[key] = 0 }

p h['a'] # 0

合并散列

* 合并散列破坏性

h1 = {"name" => 'monster'}

h2 = {"job" => "web dev"}

p h1.update(h2) # 合并了两个散列,破坏性h1会被更新 {“name"=>"monster", "job"=>"web dev"}

* 非破坏性合并

h1 = {"name" => 'monster'}

h2 = {"job" => "web dev"}

p h1.merge(h2) # h1 不会被更改

从散列中选择和丢弃元素

* select获得子散列

如果代码块返回 true 则保留元素

h = Hash[1,2,3,4,5,6]

p h.select { |k,v| k > 3} # {5=>6}

* reject丢弃元素

如果代码块返回 true 则丢弃元素

h = Hash[1,2,3,4,5,6]

p h.reject { |k,v| k > 3}

清楚散列

* {1 => ‘one’}.clear # {}

查询散列

* h.has_key?(1) # 有键为 1 返回 true

* h.include?(1) # 类似 has_key

* h.key?(1) # 类似 has_key

* h.member?(1) # 类似 has_key

* h.has_value?(‘three’) # 如果有值为 three 返回 true

* h.value?(‘three’) # 类似 has_value?

* h.empty? # 没有任何键值对返回 true

* h.size # 键值对数量

散列作为方法最后的参数

def add(name, info)
  p info
end
# 调用方式1
add('monsterooo', {
  state: 'China',
  job: 'dev'
}) # {:state=>"China", :job=>"dev"}
# 如果最后一个参数是散列,那么可以直接在参数最后放置键值对模式
add('monsterooo', state: 'China', job: 'dev')
# {:state=>"China", :job=>"dev"}

Enumerable 和 Enumerator 集合类型核心

#Ruby/知识记录

以上是我学习 Ruby 的笔记。后面还会更新 😶

感觉楼主要被批评了,不能把笔记放在 bbs 里当博客用的。😂

楼主加油~继续更新,我会常来支持你的!

n = 1
text = <<"EOM"
文本 #{n}
EOM
p text 
adamshen 回复

🙀 我不太了解。

w569893882 回复

😀 持续努力学习

w569893882 回复

对对 加和不加相等

给大家分享套 Ruby 视频教程 https://www.sucaihuo.com/video/181.html

需要 登录 后方可回复, 如果你还没有账号请 注册新账号