* ||= 或者等于运算符
* **= 产生一个 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_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 方法。这样的方法被标记为有”危险”的方法。
除了传统的字符串引用之外,还有另外一种引用格式为:%char{text}
方式,char
是一个特殊字符。
* %q{abc} # 同单引号
* %Q{ab#{var}c} # 同双引号
* %{ab#{var}c} # 同双引号
* %限定符号可以使用任意字符,只要两边能够匹配即可。还有限定符不能由字母组成
如果要进入 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 个类来操作:Time
、Date
、DateTime
# 提供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.sec
Time 对象并没有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"}
#Ruby/知识记录
以上是我学习 Ruby 的笔记。后面还会更新