0 安装
https://www.ruby-lang.org/zh_cn/downloads/
windows安装exe程序的
ruby -v 查看是否安装成功
irb 进入ruby交互命令行
面向对象的脚本语言
1 注释:
单行注释 使用#
多行注释:使用=begin =end,=要顶格写
之后全注释 使用 END 对之后所有的内容都不起作用了
2 变量命名规范 和 作用域
Ruby 标识符的名称可以包含字母、数字和下划线字符( _ ),标识符是变量、常量和方法的名称,Ruby 标识符是大小写敏感的
局部变量 函数命名 字母 数字 下划线
全局变量 常量 大写字母
实例变量,只作用于本实例 @开头 @后不能直接跟数字
类变量 ,只作用于此类,@@开头 @后不能直接跟数字
类名 模块名字 首字母大写
3 操作符
运算操作符
+ - * ** / %
比较操作符
==、!=、> 、>= 、< 、<=
逻辑操作符
&&逻辑与、 ||逻辑或、 !逻辑非
位运算操作符(不常用)
&:与AND |:或OR ^:异或 位反转 << 左移位 >>右移位
输出
#puts print 都是向控制台打印字符,其中puts带回车换行符
4 数据类型:数字、符号、字符、数组、哈希表、范围
4.1 数字
4.2 符号
4.3 字符串
字符串中引号的使用
单引号 双引号 引号中的大括号的使用
# 单引号和双引号的区别
#"\n" 双引号里边的\n 正常换行,'\n'单引号里边的\n会被转义成\n字符串,不再具有换行的功能
p1 = "a\nb" #
p2 = 'c\nd' # 单引号里边的所有内容,都被当成是字符串,包括特殊字符,运算符,不再具有运算功能
puts p1
puts p2
sum = "#{1+2}"
str = '#{1+2}'
puts sum
puts str
---------
a
b
c\nd
3
#{1+2}
运算 + * <<
+:字符串连接
*星号: 字符循环 ”abc“ * 4
<<:字符串带入,右边的内容带入到左边的变量,相当于 a = a+b
参考:https://www.cnblogs.com/Stay-J/p/9236190.html
str = "abCd"
# puts str.capitalize # Abcd 首字母大写,其他小写,str1的值不变
# puts str.capitalize! # Abcd 首字母大写,其他小写,同时改变str1的值并返回
# puts str
puts str.length # 4
puts str.size # 4
puts str.include?"a" # true
puts str.insert(0,"mn") #在索引0的位置插入字符串 ->mnabCd
puts str.insert(-1,"xy") # 从最后一个索引开始添加字符串 ->mnabCdxy
print "ruby abc def".split # 字符串分割,默认分隔符为空格 ->["ruby", "abc", "def"]
print "ruby abc def".split("a") #->["ruby ", "bc def"]
'ruby abc def'.split('',4) # ["r", "u", "b", "y abc def"]
'ruby abc def'.split(' ',4) #["ruby", "abc", "def"]
print("\n============字符串替换==========")
# 字符串替换
str1 = "hello"
str1.sub(/[aeiou]/,"*") #->"h*llo" #str1= "hello"
str1.sub!(/[aeiou]/,"*") #->"h*llo" #str1= "h*llo"
# sub生成并返回替换后的字符串。而sub!会修改str本身并返回结果
str2 = "hello"
str2.gsub(/[aeiou]/,"*") #->"h*ll*" # str2 = "hello"
str2.gsub!(/[aeiou]/,"*") #->"h*ll*" # str2 = "h*ll*"
# sub只替换第一次匹配的部分,gsub替换所有匹配的部分。
puts "world".gsub(/./){|s| s[0]+" "} # -> "w o r l d" #将所有元素后加空格
str2.replace("world") # ->"world" # str2="world" replace替换整个 str
字符串删除:
str.delete([other_str]+) => new_str #删除参数交集出现的所有字符,返回一个新字符串
str. delete! ([other_str]+) => str #原字符串会被改变
irb(main):003:0> "hello".delete "l"
=> "heo"
irb(main):004:0> "hello".delete "l","lo"
=> "heo"
irb(main):005:0> "hello".delete "lo"
=> "he"
irb(main):006:0>
去掉空白:
str. strip => new_str #删除头部和尾部的空白
str.strip! =>str #删除头部和尾部的空白,原字符串本身被改变,若无删除动作,则返回nil,str本身不变
str.lstrip => new_str #删除头部的空白
str. lstrip !=> str #删除头部的空白,原字符串本身被改变,若头部无空白,则返回nil,str本身不变
str.rstrip => new_str #删除尾部的空白
str.rstrip !=> str #删除尾部的空白,原字符串本身被改变,若尾部无空白,则返回nil,str本身不变
p " abc\n".lstrip #=>"abc\n"
p "\t abc\n".lstrip #=> "abc\n"
p "abc\n".lstrip #=> "abc\n"
str = "\nabc"
p str.lstrip #=>"abc"
p str #=>"\nabc" (无变化)
str = " abc"
p str.lstrip! #=>"abc"
p str #=>"abc" (有变化)
str = "abc"
p str.lstrip! #=>nil
p str #=>"abc"
字符串反转
"hello".reverse -> "olleh"
去掉重复的字符,字符串中,连续重复的字符,
str.squeeze([other_str]*) => new_str
str.squeeze!([other_str]*) => str #str本身被改变,若无删除动作,返回nil,str不变
irb(main):009:0> "hello".squeeze
=> "helo"
irb(main):011:0> "h el".squeeze
=> "h el"
irb(main):012:0> "he he".squeeze
=> "he he"
irb(main):013:0>
删除最后的字符
str.chop :删除字符串str的最后一个字符,并返回新字符串
#若字符串以\r\n结尾,则两个字符都删去
#若字符串为空串,则返回空串
str.chop !:修改str本身并返回结果,若没做修改,则返回nil。
"string\r\n".chop #->"string"
"string\n\r".chop #->"string\n"
"string".chop #->"strin"
"".chop #->""
str.chomp(endstr) :删除str的后缀endstr,如果未指定endstr,则删除回车换行符(\r、\n和\r\n);若endstr的取值是空的话,将不作任何的动作。
str.chomp!(endstr) :修改str本身并返回结果,若没做修改,则返回nil。
"hello\r\n".chomp #->"hello"
"hello".chomp("lo") #->"hel"
"hello".chomp("l") #->“hello"
格式字符串
str % arg
name = "Bob"
age = 28
str = sprintf("Hi, %s... I see you're %d years old.", name, age)
str = "Moby-Dick"
s1 = str.ljust(13) #"Moby-Dick "
s2 = str.center(13) #" Moby-Dick "
s3 = str.rjust(13) #" Moby-Dick"
s4 = str.rjust(13,'*') #"****Moby-Dick"
str.center(1).id== str.id # => false #返回原字符串的拷贝
分别返回居中、靠左、靠右的字符串,当字符串长度超过width时,将返回原字符串的拷贝;若使用了第二参数padding的话,将使用padding来填充空白。
字符串大小写
str.capitalize:将首字符(若为字母的话)改为大写字母,其余的改为小写字母,生成并返回修改后的字符串。。
str.capitalize!:会修改str本身并返回结果,若未作修改时返回nil。
str.downcase:将字符串中的大写字母都改为小写字母,生成并返回修改后的字符串
str.downcase!:会修改str本身并返回结果,若没有作修改,则返回nil.
str.upcase:将字符串中的小写字母都改为大写字母,生成并返回修改后的字符串
str.upcase!:会修改str本身并返回结果,若没有作修改,则返回nil.
str. swapcase:将所有的大写字母改为小写字母,小写字母改为大写字母,生成并返回修改后的字符串
str. swapcase!:会修改str本身并返回结果,若没有作修改,则返回nil.
字符串的匹配???
字符串的子串.
tr[num1,num2]:num1代表取字符串的偏移位置,num2表示取的长度,其中num1可以是负数:
str = "Humpty Dumpty"
sub1 = str[7,4] # "Dump"
sub2 = str[7,99] # "Dumpty" (超过的长度按实际长度来取)
sub3 = str[10,-4] # nil (长度为负数了)
str1 = "Alice"
sub1 = str1[-3,3] # "ice"
Range取子串:利用脚标取子串
str = "abcd efg"
sub1 = str[0..3] # "abcd"
sub2 = str[-4..-1] # " efg"
sub3 = str[-1..-4] # “”
sub4 = str[9..10] # nil
str = "Alistair Cooke"
sub1 = str[/l..t/] # "list"
sub2 = str[/s.*r/] # "stair"
sub3 = str[/foo/] # nil
如果给出的是一个字符串,则如果目标字符串中含有这个给出的字符串,则返回这个给出的字符串,否则返回nil:
str = "theater"
sub1 = str["heat"] # "heat"
sub2 = str["eat"] # "eat"
sub4 = str["beat"] # nil
如果给出的是一个数字,则返回的是该数字对应索引处字符:
str = "abc"
res = str[0] # a
res = str[10] # nil
字符串的匹配:参考
https://www.cnblogs.com/Stay-J/p/9236190.html
4.4 数组
1 定义数组:数组中可包含任何数据类型的数据
定义的时候赋值
a1 = [1,2,“a”,[1,‘d’]]
puts a1
定义的时候不赋值,之后再赋值
a2 = Array.new()
2 循环打印数组的元素
a1 = [1,2,“a”,[1,‘d’]]
#方法1
a1.each do |a|
puts “la#{a}”
end
#方法2 循环打印数组的元素和对应的下标
a1.each_with_index do |a,i|
puts “下标: #{i},元素: #{a}”
end
3 数组连接,把数组中的每个元素连接起来,并用,隔开
puts a1.join(’,’)
4 判断是否是数组
if a1.respond_to?(“each”) # a1.respond_to?(“each_with_index”)简单判断就是判断a1有没有each这个方法,如果没有,则a1不能作为数组
数组操作方法总结:https://www.cnblogs.com/lmg-jie/p/9639515.html
4.5 哈希表
格式一: key => value key是字符串的书写格式
point_hash = {"lili" => 90,"xiao" => 80, "wang" => "90"}```
irb(main):010:0> point_hash = {"lili" => 90,"xiao" => 80, "wang" => "90"}
=> {"lili"=>90, "xiao"=>80, "wang"=>"90"}
irb(main):011:0> puts point_hash
{"lili"=>90, "xiao"=>80, "wang"=>"90"}
=> nil
irb(main):012:0> puts point_hash["lili"]
90
=> nil
格式二: 变量名字 : value
player = {name: "lili", age:20, point: 90}
puts player[:name] + ", " + player[:point].to_s # lili, 90
4.6 范围
Ruby 使用 ‘’…’’ 和 ‘’…’’ 范围运算符创建这些序列
(1..5) #==> 1, 2, 3, 4, 5
(1...5) #==> 1, 2, 3, 4
('a'..'d') #==> 'a', 'b', 'c', 'd'
digits = 1..4
puts digits.include?(5)
ret = digits.min
puts "Min value is #{ret}"
ret = digits.max
puts "Max value is #{ret}"
ret = digits.reject {|i| i < 3 } # 满足条件的留下
puts "Rejected values are #{ret}"
digits.each do |digit|
puts "In Loop #{digit}"
end
---------------
false
Min value is 1
Max value is 4
Rejected values are 3,4
In Loop 1
In Loop 2
In Loop 3
In Loop 4
4.7 类型转换 字符与数值转换
字符 to 数值
数值 to 字符
FG = "50"
P3 = "40"
FT = "90"
puts FG+P3+FT #504090
#转化整形 180
puts FG.to_i + P3.to_i + FT.to_i
#转整型相加 转字符再连接字符串 输出180字符串
puts (FG.to_i + P3.to_i + FT.to_i).to_s + "字符串"
puts FG
FG.to_i
puts FG
#转整型再转浮点型 50.0
puts FG.to_i.to_f
puts 123.2.to_i
5 流程控制
5.1条件控制
if/else
if/elsif z这里注意和python书写不一样
unless 理解为只要不,跟if相反,unless后边如果假,走逻辑,如果是真,走else。 不建议使用
case/when/else
# 运动员工资,输出3500万美元
game_point = 30
if game_point >=30
puts "3500万美元"
elsif game_point >= 20
puts "2000万美元"
else
puts "终止合同"
end
# 输出星期 ,输出 星期三
week_day = 3
case week_day
when 0,7
puts "星期日"
when 1
puts "星期一"
when 2
puts "星期二"
when 3
puts "星期三"
when 4
puts "星期四"
when 5
puts "星期五"
when 6
puts "星期六\n"
else
raise Exception.new("没这天")
end
# unless 不常用,输出 10小于等于10
a = 10
unless a<=10
print("#{a}大于10")
else
print("#{a}小于等于10")
end
三目运算符,用来代替if else
条件?处理1:处理2
条件:逻辑表达式,返回bool值
处理1:当条件为真时,执行
处理2:当条件为假时,执行
point >=30 ? "mvp球员":"一般球员"
5.2循环处理
1一般循环 for while until(不常用)
循环数组
#for 循环
lst = [1,2]
for i in lst do
puts i
end
# 循环1-5 1..5 表示 闭区间[1,5]
puts "循环1-5"
for num in 1..5 do
puts num
end
# 循环1-4 1...5 表示 左闭右开区间[1,5)
puts "循环1-4"
for num in 1...5 do
puts num
end
# while循环
index1 = 0
while index1<5 do
puts "index1的值是:"+index1.to_s
index1 += 1
end
# until循环
puts "until循环"
index2 = 0
until index2 ==5 do #意思是, do index加一,直到满足index==5,停止
puts "index2的值是:"+index2.to_s
index2 += 1
end
2 特殊循环 each times step
each: 循环集合 数组里边的每个元组
times: 指定循环次数
step: 设置循环步长
lst = [1,2,'a']
#格式1 {}大括号循环体
lst.each { |i|
print "#{i} "
}
#格式2 do end 循环
puts "\n格式2"
lst.each do |i|
print "#{i} "
end
# 数组元素和下标一块循环,do end格式
puts "\n下标和元素一块循环"
lst.each_with_index do |con,index|
puts "元素是:#{con} 下标是:#{index}"
end
# 大括号格式循环
lst.each_with_index {|con,index|
puts "#{con},#{index}"
}
#times循环,指定循环次数
puts "times循环"
5.times do |con|
print "#{con} "
end
# 设置循环步长 step
puts "\n从1循环到10,步长为3"
1.step(10,3) do |i|
print "#{i} "
end
------ 输出结果:
1 2 a
格式2
1 2 a
下标和元素一块循环
元素是:1 下标是:0
元素是:2 下标是:1
元素是:a 下标是:2
times循环
0 1 2 3 4
从1循环到10,步长为3
1 4 7 10
3 特殊循环 upto downto 升序和降序循环
2.upto(5) { |i|
puts i # 2 3 4 5
}
8.downto(6){|i|
puts i # 8 7 6
}
6 异常处理
begin
rescue/else/ensure
end
begin
#正常业务流
puts "开始业务流"
rescue => exception
#发生错误,走这里
puts "发生异常走这里"
else
#没发生错误,处理
puts "没发生异常,走这里"
ensure
#最后处理,不管有没有错误,都走这里
puts "无论是否出错,都走扫尾处理,比如用来写日志"
end
------
开始业务流
没发生异常,走这里
无论是否出错,都走扫尾处理,比如用来写日志
-----------------------------------------------------
begin
#正常业务流
10/0
puts "开始业务流"
rescue => exception
#发生错误,走这里
puts "发生异常:#{exception}"
else
#没发生错误,处理
puts "没发生异常,走这里"
ensure
#最后处理,不管有没有错误,都走这里
puts "无论是否出错,都走扫尾处理,比如用来写日志"
end
---------
发生异常:divided by 0
无论是否出错,都走扫尾处理,比如用来写日志
7 函数
Math.sqrt(9) 开平方
创建一个函数
传一个参数
给一个默认值
def sayHello
puts "hello"
end
sayHello
# 传参数
def sayHello(name)
puts "hello,#{name}"
end
sayHello("lili")
# 设定一个默认值,调用的时候不传参就使用默认值
def sayHello(name="默认值")
puts "hello,#{name}"
end
sayHello()
-----
hello
hello,lili
hello,默认值
8 对象
实例变量 @name是实例变量,能够被该类或者子类继承使用
对象的方法
class Player
def initialize(name="默认值") # 构造函数
@name = name
end
def show()
puts "player: #{@name}"
end
def show2()
end
end
# instance_methods() 实例的所有方法
puts Player.instance_methods(false) # false 只是打印自己定义的方法
lili = Player.new("lili")
# 实例.respond_to?("属性"/"方法") 判断实例是否有某个属性/方法
# 实例.send("属性"/"方法") 调用属性或者方法
if lili.respond_to?("show") # 判断是否有show方法,,这里加入if是考虑到设计模式的原因
lili.send("show") #有的话就调用
end
---------
show
show2
player: lili
使用对象的属性
attr_accessor:定义对象的可读写属性
class Player
attr_accessor :score#,:title # 定义实例对象可以访问和修改的属性
def initialize(name="lili",score=100) # 构造函数
@name = name
@score = score
end
def show()
puts "player: #{@name}"
puts "score: #{@score}"
end
end
lili = Player.new()
lili.show()
puts "name is " + lili.respond_to?("name").to_s
puts "score is " + lili.respond_to?("score").to_s
lili.score = 90
puts lili.score
# puts lili.name 就会报错
------
player: lili
score: 100
name is false
score is true
90
Class类再入门
静态方法:就是这个类不用实例化,就能使用的方法叫做静态方法。只能被类本身调用,不能被实例调用
class Player
def initialize(name="默认值") # 构造函数
@name = name
end
def show
puts "player: #{@name}"
end
def self.toStr # 这个是类方法,类实例不能调用
puts "这是静态方法,只能类自己调用,类实例不能调用"
end
end
lili = Player.new("lili")
lili.show
# lili.toStr 不能调用,会报错
Player.toStr
Player::toStr
类继承
class Player
def initialize(name="默认值") # 构造函数
@name = name
end
def show
puts "player: #{@name}"
end
def self.toStr # 这个是类方法,类实例不能调用
puts "这是静态方法,只能类自己调用,类实例不能调用"
end
end
class SkatingPlayer < Player
def skate
puts "我会喜欢滑冰"
end
end
SkatingPlayer.toStr # 子类可以调用父类的静态方法
son = SkatingPlayer.new("son")
son.show
son.skate
--------
player: son
我会喜欢滑冰
这是静态方法,只能类自己调用,类实例不能调用
9 模块
定义模块 module BaseFunc
9 文件读取
puts gets putc print
gets: gets 语句可用于获取来自名为 STDIN 的标准屏幕的用户输入。
puts "Enter a value :"
val = gets
puts val
Enter a value :
This is entered value
This is entered value
putc :putc 语句可用于依次输出一个字符。
str="Hello Ruby!"
putc str # H
打开关闭文件
File.new() File.open() 不同点是 File.open 方法可与块关联,而 File.new 方法不能。
aFile = File.new("filename", "mode")
# ... 处理文件
aFile.close
File.open("filename", "mode") do |aFile|
# ... process the file
end
打开文件的模式
r 只读 ;r+ 读写; 文件指针被放置在开头
w 只写; w+ 读写;
a :只写; a+ 读写 文件指针被放置在末尾