ruby语法 一

544 阅读6分钟

ruby中使用到的一切数据类型(数值、字符串、对象、类)都是对象

def run
 puts '-' * 30
end
//方法调用
run
self.send(:run)
//打印
puts self
puts self.class

=========输出结果==========

------------------------------
------------------------------
main
Object

类对象和父类

类似OC中类对象和元类的概念

image.png

数字也是一个对象

image.png

数值、字符串

# 数值类型

pp 1 + 3
pp 2 * 6
pp 1.class

#字符类型
#作为字符串单引号和双引号都一样,字符串表达式必须用双引号

str = 'xxx'
str1 = "xxx"

name = "hanghang"

def run
 2
end
desc = "name is #{name} ,age is #{run}"
puts desc

#输出结果:

4
12
Integer
name is hanghang ,age is 2

%

str = "| %s | %s | %s | %s |" % [
  "捷克VS葡萄牙",
  "德国VS希腊",
  "西班牙VS法国",
  "英格兰VS意大利"
]
puts str

#输出结果:
捷克VS葡萄牙 | 德国VS希腊 | 西班牙VS法国 | 英格兰VS意大利

sprintf

a=10
b=20

str1 = sprintf('first=%d, second=%d', a, b)
str2 = sprintf('first=%{first}, second=%{second}', first: a, second: b)

puts str1
puts str2

#输出结果:
first=10, second=20
first=10, second=20

format

a=10
b=20

str = format('first=%{first} ,second=%{second}', first: a, second: b)

puts str

#输出结果:
first=10 ,second=20

here document

fat_cat = <<MY_HEREDOC
I'll do a list:
\t* Cat food
\t* Fishies
\t* Catnip\n\t* Grass
MY_HEREDOC

puts fat_cat

#输出结果:

I'll do a list:
* Cat food
* Fishies
* Catnip
* Grass

bool

除了 false 和 nil, 其他都表示 true

if 0
 puts '-' * 20
end

#输出结果:
--------------------

any?, all?, one?, none?

puts [true,false,true,false].all? #都是true
puts [true,false,true,false].any? #一个以上true
puts [true,false,true,false].one? #一个true
puts [true,false,true,false].none? #没有true

#输出结果:
false
true
false
false
//迭代器
pp %w[cat dog pig].all?{|word| word.length >= 3}
pp %w[cat bear pig].all?{|word| word.length >= 4}
pp [nil,**true**,99].all?
pp [].all?

#输出结果:
true
false
false
true

判断变量是否是布尔类型

def run(val)
 if val.is_a?(TrueClass)
   puts 'success'
 else
   puts 'fail'
   end
 end
 run(nil)
 run([])
 run({})
 run(false)
 run(true)
 
#输出结果:
fail
fail
fail
fail
success

symbol

def puts_class(cls)
  puts cls.class
end

puts_class("123") #=> "123"
puts_class(:'123') #=> :123

#输出结果:
String
Symbol

字符串类型

str1 = 'dog'
str2 = 'dog'
str3 = 'dog'
str4 = 'dog'

puts(str1.object_id())
puts(str2.object_id())
puts(str3.object_id())
puts(str4.object_id())

#输出结果:
60
80
100
120

symbol类型

symb1 = :dog
symb2 = :dog
symb3 = :dog
symb4 = :dog

puts(symb1.object_id())
puts(symb2.object_id())
puts(symb3.object_id())
puts(symb4.object_id())

#输出结果:
1020828
1020828
1020828
1020828

hash

require 'pp'

h1 = {
    "name" => 'zhangsan',
    "age" => 99
}

h2 = {
    name:'zhangsan',
    age:99
}

pp h1
pp h2

# 对应key类型去取
puts h1['name']
puts h2[:name]

# string 与 symbol 相互转换
pp "123".to_sym.to_s

h2.each do |k,v|
    puts k
    puts v
end

#输出结果:

{"name"=>"zhangsan", "age"=>99}
{:name=>"zhangsan", :age=>99}
zhangsan
zhangsan
"123"
name
zhangsan
age
99

struct

require 'pp'

h1 = {
    "name" => 'zhangsan',
    "age" => 99
}

puts h1['name']
puts h1['age']

Person = Struct.new(:name,:age) do
 def run
    puts name
    puts age
 end
end

obj = Person.new('hanghang',99)
puts obj.name
puts obj.age

#输出结果:

zhangsan
99
hanghang
99
hanghang
99

array

require 'pp'

arr = []

arr << '1'
pp arr
#头插
arr.unshift("2")
pp arr

#遍历
arr.each do |e|
   puts e
end

arr.each_with_index do |e,index|
   
   puts "index:#{index},e:#{e}"
   
end

arr2 = [1,2,3,nil,4,nil]
puts arr2
puts arr2.compact #去空

arr3 = [1,2,3,4,[5,6,7],8]
pp arr3
pp arr3.flatten #数组整合

#输出结果:

["1"]
["2", "1"]
2
1
index:0,e:2
index:1,e:1
1
2
3

4

1
2
3
4
[1, 2, 3, 4, [5, 6, 7], 8]
[1, 2, 3, 4, 5, 6, 7, 8]

方法

require 'pp'

def run(name,age)
    puts name
    puts age
end

run('hanghang',3)

def run(name,age,options = {})
    puts name
    puts age
    puts options
end

run('yang',31,{addr:'北苑',sex:1})

def run(arr) #地址引用
   arr << '4'
end

arr = [1,2,3]
puts arr
puts '-' * 20
run(arr)
puts arr

#输出结果:

hanghang
3
yang
31
{:addr=>"北苑", :sex=>1}
1
2
3
--------------------
1
2
3
4

隐式返回值

require 'pp'

# 方法隐性返回值
def eat
   1
   2
   x = 3
end

pp eat

def jump
  return 1
   2
   3
end

pp jump

#输出结果:
3
1

代码块

不带参数

require 'pp'

def test
#执行代码块 可以携带参数
yield
end

test do
puts '回调内容'
end

#输出结果:
回调内容

带参数

require 'pp'

def test

yield 1,2,3 if block_given? #判断是否传入代码块
end

test do
puts '回调内容'
end

test {|a,b,c|
 puts "打印参数:#{a},#{b},#{c}"
}

test

#输出结果:
回调内容
打印参数:1,2,3

require 'pp'

def test(name, age, &block)

    block.call(age + 1)
end

test('hanghang',3) {|a|
 puts "打印参数:#{a}"
}

#输出结果:
打印参数:4

对象

对象方法

require 'pp'

class Person
   def run
   puts '对象方法'
   end
end

Person.new.run

#输出结果:
对象方法
require 'pp'

pp self
pp self.class

def run
    pp self
    pp self.class
end
run

puts '-' * 30

class Person
    pp self
    pp self.class
    
    #定义对象方法
    def run
        pp self
        pp self.class
    end
    
    #定义类方法
    def self.run 
        pp self
        pp self.class
    end
    
end

puts '-' * 30

module Animal
   pp self
   pp self.class
end

puts '-' * 30
Person.new.run
Person.run


#输出结果:
main
Object
main
Object
------------------------------
Person
Class
------------------------------
Animal
Module
------------------------------
#<Person:0x00007fb3ef046aa0>
Person
Person
Class

属性

require 'pp'

class Person
 def name
    @name
 end
 
 def name= (_name)
    @name = _name
 end
 
end

p = Person.new
p.name = 'hanghang'
pp p.name

#输出结果:
"hanghang"

require 'pp'

class Person
 
 attr_accessor :name,:age
 
end

p = Person.new
p.name = 'hanghang'
p.age = 3

pp p.name
pp p.age

#输出结果:
"hanghang"
3

to_s

class Cat
 
 attr_accessor :color
 
 def initialize(color)
     @color = color
 end
 
 def to_s
    "I'm #{color} Cat"
 end
 
end

puts Cat.new("blue")

#输出结果:
I'm blue Cat

inspect

require 'pp'

class Cat
 
 attr_accessor :color
 
 def initialize(color)
     @color = color
 end
 
 def inspect
    "<#{self.class} color: #{color}>"
 end
 
end

puts Cat.new("blue")
puts Cat.new("white").to_s
puts Cat.new("red").inspect

#输出结果:
#<Cat:0x00007ff46783c648>
#<Cat:0x00007ff46783c300>
<Cat color: red>

继承

require 'pp'

class Animal
    
 def run
     puts "animal run -----"
 end
 
 def sleep
     puts "animal sleep -----"
 end
 
end

class Dog < Animal
end

Dog.new.run
Dog.new.sleep

#输出结果:
animal run -----
animal sleep -----

抽象


require 'pp'

class Animal
    
 def run
     raise '必须实现run方法'
 end
 
 def sleep
     raise '必须实现sleep方法'
 end
 
end

class Dog < Animal
    def run
    end
    
    def sleep
    end
end

Dog.new.run
Dog.new.sleep

单列

require 'pp'
require 'singleton'

class Animal
    
include(Singleton)
end

pp Animal.instance
pp Animal.instance
pp Animal.instance
pp Animal.instance

#输出结果:
#<Animal:0x00007faae6061c18>
#<Animal:0x00007faae6061c18>
#<Animal:0x00007faae6061c18>
#<Animal:0x00007faae6061c18>
require 'pp'

class Person
    
def sleep
end
    
end

obj = Person.new

#方法属于singletonclass
def obj.run
   pp self
   pp self.singleton_class
end

run
pp obj.method(:sleep).owner
pp obj.method(:run).owner

#输出结果:
#<Person:0x00007fea840d8bc8>
#<Class:#<Person:0x00007fea840d8bc8>>
Person
#<Class:#<Person:0x00007fea840d8bc8>>

eigen class

require 'pp'

class Person
    
    class << self
    # 类方法、类属性作用域
    def run
       puts "eigen class"
    end
    
    attr_accessor :name
end
    
end

Person.run
Person.name = '杭杭'
puts Person.name

#输出结果:
eigen class
杭杭

方法名!=> 会修改成员变量

require 'pp'

class Person
    attr_accessor :name
    attr_accessor :age
  
    def run
       puts name #=> 读取成员变量
       puts age
    end

    #=> 表示这个方法会修改属性或者成员变量
    def run!
       @name += '~~' #=> 改变成员变量
       @age  += 1
    end
    
    #=> 表示这个方法返回值是布尔类型
    def sleep?
       return true
    end
    
end

obj = Person.new
obj.name = 'hanghang'
obj.age = 99

obj.run!
obj.run

#输出结果:
hanghang~~
100

变量

全局变量

$name = 'hanghang'

def run
 puts $name
end

run

class Person
   def run
    $name = 'jiajia'
   end
   
   def self.sleep
     puts $name
   end
end

Person.new.run
Person.sleep

#输出结果:
hanghang
jiajia

成员变量

require 'pp'

class Person
    
   attr_accessor :name,:age
   
   def initialize(name,age)
    @name = name #成员变量
    @age = age
    
    @@addr = 'defalut' #=> 类成员变量不能直接访问
   end
   
   def self.sleep
     @@addr = 'xxx'
     puts @@addr
   end
end

obj = Person.new('hanghang',29)
pp obj.name
pp obj.age

Person.sleep

#输出结果:
"hanghang"
29
xxx

常量

require 'pp'

MY_NAME = 'hanghang'
puts MY_NAME

#输出结果:
hanghang

环境变量

require 'pp'

#export name=hanghang 配置环境变量
#echo $name 获取环境变量

# pp ENV #=> hash 对象
pp ENV['name']

#ENV['name'] = 'haha' =>不会成功,开启新的子进程

#输出结果:
hanghang

path变量

require 'pp'

# path 变量 数组形式打印
paths = ENV['PATH'].split(File::PATH_SEPARATOR)
#=> 头插
paths.unshift('/Users/yutangzhao/Desktop')

pp paths
#只作用于ruby脚本,shell进程不生效
ENV['PATH'] = paths.join(':')
pp ENV['PATH']


#输出结果:
["/Users/yutangzhao/.rvm/gems/ruby-2.7.2/bin",
 "/Users/yutangzhao/.rvm/gems/ruby-2.7.2@global/bin",
 "/Users/yutangzhao/.rvm/rubies/ruby-2.7.2/bin",
 "/usr/local/bin",
 "/usr/bin",
 "/bin",
 "/usr/sbin",
 "/sbin",
 "/Library/Apple/usr/bin",
 "/Users/yutangzhao/.rvm/bin"]
 "/Users/yutangzhao/Desktop:/Users/yutangzhao/.rvm/gems/ruby-2.7.2/bin:/Users/yutangzhao/.rvm/gems/ruby-2.7.2@global/bin:/Users/yutangzhao/.rvm/rubies/ruby-2.7.2/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/Library/Apple/usr/bin:/Users/yutangzhao/.rvm/bin"

条件语句

require 'pp'

#if
if true
   puts '-' * 40
end

#if 条件表达式
puts '*' * 40 if true

#unless
unless false
    puts '&' * 40
end

#for 循环
for i in 0..5
    puts "局部变量值为#{i}"
end

#break
for i in 0..5
    if i > 2 then
        break
    end
    puts "变量值为#{i}"
end

#next
for i in 0..5
    if i < 2 then
        next
    end
    puts "打印值为#{i}"
end

#while

while true do
   puts "条件成立"
   break
end

#输出结果:
----------------------------------------
****************************************
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
局部变量值为0
局部变量值为1
局部变量值为2
局部变量值为3
局部变量值为4
局部变量值为5
变量值为0
变量值为1
变量值为2
打印值为2
打印值为3
打印值为4
打印值为5
条件成立

文件操作

require 'pp'

# puts File.read('haha.txt')

#f = File.open('haha.txt','r') #r 只读
#puts f.read

#File.write('haha.txt','123456\n',mode:'w+') #文件不存在会创建


File.open('haha.txt','w+'){|f|
    f.write "#{Time.now} user log"
}

#重命名
File.rename('haha.txt','hang.txt')

#文件大小
puts File.size('hang.txt')
#判断文件是否存在
puts File.exists?('hang.txt')
#获取后缀名
puts File.extname('hang.txt')
#获取文件路径
puts File.dirname('/Users/xxx/Movies/Ruby/hang.txt')
#是否是目录
puts File.directory?('hang')
#目录下所有的信息
puts File.stat('/Users/yutangzhao/Movies/Ruby').atime


#输出结果:
34
true
.txt
/Users/xxx/Movies/Ruby
false
2022-05-30 10:43:00 +0800

目录操作

require 'pp'

#目录下所有文件
pp Dir.glob("*")

# 包含‘spec’的所有文件名
pp Dir.glob('*spec*')

# 目录下所有ruby文件
pp Dir.glob('*.rb')

# 递归所有目录下所有文件
pp Dir.glob('**/**')

# 递归所有目录下所有目录
pp Dir.glob('**/**/')

#获取当前所在的目录
pp Dir.pwd

#判断目录是否为空
pp Dir.empty?('/Users')
#判断目录是否存在
pp Dir.exists?('/Users/yutangzhao/Movies/Ruby')
#创建一个目录
Dir.mkdir('Test')

#输出结果:
["hang.txt", "main.rb"]
[]
["main.rb"]
["hang.txt", "main.rb"]
[]
"/Users/yutangzhao/Movies/Ruby"
false
true

json操作

require 'pp'
require 'json'
require 'ostruct'

#转成symbolkey
#json = JSON.parse(File.read('cat.json'),symbolize_names:true)
#pp json[:name]

#对象属性方式取值
#json = JSON.parse(File.read('cat.json'),object_class:OpenStruct)
#pp json.name
#pp json.age

json = JSON.parse(File.read('cat.json'))
File.write('yang.json',JSON.pretty_generate(json),mode:'w+')

yaml

---
name: hanghang
age : 3
favor:
 - aaa
 - bbb
 - ccc
require 'pp'
require 'yaml'

h = YAML.load_file('yang.yml')
pp h

puts h.to_yaml
File.write('hang.yml',h.to_yaml,mode:'w+')

#输出结果:
{"name"=>"hanghang", "age"=>3, "favor"=>["aaa", "bbb", "ccc"]}
---
name: hanghang
age: 3
favor:
- aaa
- bbb
- ccc

pathname

require 'pp'
require 'pathname'

path = Pathname.new('/Users/yutangzhao/Movies/Ruby/hang.txt')
#文件夹大小
pp path.size
#是否是文件夹
pp path.directory?
#绝对路径
pp path.absolute?
#相对路径
pp path.relative?
#是否可执行文件
pp path.executable?
#是否可写
pp path.writable?
#是否可读
pp path.readable?
#文件名
pp path.basename
#目录名
pp path.dirname
#扩展名
pp path.extname

#输出结果:
34
false
true
false
false
true
true
#<Pathname:hang.txt>
#<Pathname:/Users/yutangzhao/Movies/Ruby>
".txt"

require 'pp'
require 'pathname'

pn = Pathname.new('/Users/yutangzhao/Movies/Ruby').join('yang').join('hang')
pp pn.exist?
pp pn
#创建目录
pn.mkpath
puts '-' * 50

#创建文件
pn1 = pn.join('tang.txt')
pp pn1.exist?
pn1.write('xxxxx',mode:'a+')
pn1.write('\n',mode:'a+')

pp pn1.exist?
pp pn1.file?
puts '-' * 50

#读取文件
pp pn1.read

pn1.each_line {|line|
    pp line
}

pp pn1.zero?
pp pn1.empty?
puts '*' * 50

pn1.rename('/Users/yutangzhao/Movies/Ruby/jia.txt')
pp pn1.exist?

#输出结果:
false
#<Pathname:/Users/yutangzhao/Movies/Ruby/yang/hang>
--------------------------------------------------
false
true
true
--------------------------------------------------
"xxxxx\\n"
"xxxxx\\n"
false
false
**************************************************
false

删除文件

require 'pp'
require 'pathname'

#删除文件
pn = Pathname.new('/Users/yutangzhao/Movies/Ruby/jia.txt')
if pn.exist?
    pn.delete
end

pp pn.exist?
puts '*' * 40

#删除目录 如果还有子目录则会报错 Directory not empty @ dir_s_rmdir
pn1 = Pathname.new('/Users/yutangzhao/Movies/Ruby/yang/hang')
pn1.delete #=> FileUtils.rm_rf()替代

to_path

require 'pp'
require 'pathname'

#to_path
pn = Pathname.new('/Users/yutangzhao/Movies/Ruby')
pp pn
pp pn.to_path
pp pn.to_s

puts '*' * 40

pn1 = Pathname.new('../main.rb')
pp pn1
pp pn1.to_path
pp pn1.to_s

#输出结果:

#<Pathname:/Users/yutangzhao/Movies/Ruby>
"/Users/yutangzhao/Movies/Ruby"
"/Users/yutangzhao/Movies/Ruby"
****************************************
#<Pathname:../main.rb>
"../main.rb"
"../main.rb"

路径拼接

require 'pp'
require 'pathname'

#to_path
pn = Pathname.new('/Users/yutangzhao/Movies/Ruby').join('hello').join('world')
pp pn
pp pn.to_s

puts '*' * 40

pn1 = Pathname.new('/Users/yutangzhao/Movies/Ruby') +'hello' + 'world'
#=> 和上面等价
#pn1 = Pathname.new('/Users/yutangzhao/Movies/Ruby') +'hello/world'
pp pn1
pp pn1.to_s


#输出结果:
#<Pathname:/Users/yutangzhao/Movies/Ruby/hello/world>
"/Users/yutangzhao/Movies/Ruby/hello/world"
****************************************
#<Pathname:/Users/yutangzhao/Movies/Ruby/hello/world>
"/Users/yutangzhao/Movies/Ruby/hello/world"

相对路径拼接

require 'pp'
require 'pathname'

#相对路径拼接到指定路径
pn = Pathname.new('/Users/yutangzhao/Movies/Ruby/Test/http.rb') + '../main.rb'
pp pn
pp pn.to_s

#输出结果:
#<Pathname:/Users/yutangzhao/Movies/Ruby/Test/main.rb>
"/Users/yutangzhao/Movies/Ruby/Test/main.rb"

expand_path

require 'pp'
require 'pathname'

#相对路径拼接到指定路径
pn = Pathname.new('../main.rb')
pp pn.to_path

pp '*' * 40
#当前目录作为展开路径
pn1 = pn.expand_path
pp pn1.to_path
#传入当前路径
pn2 = pn1.expand_path(Dir.pwd)
pp pn2.to_path

#扩展其他路径
pn3 = pn.expand_path('/Users/yutangzhao/Movies/Ruby/Test/http.rb')
pp pn3.to_path

#输出结果:
"../main.rb"
"****************************************"
"/Users/yutangzhao/Movies/main.rb"
"/Users/yutangzhao/Movies/main.rb"
"/Users/yutangzhao/Movies/Ruby/Test/main.rb"

遍历路径

require 'pp'
require 'pathname'

#遍历路径
path = '/Users/yutangzhao/Movies/Ruby';
pn = Pathname.new(path)
pp pn.children

pp '*' * 40

#默认为true 打印绝对路径,false只打印文件名
pp pn.children(false)

pp '*' * 40

#遍历路径下的txt文件
pp Pathname.new(path).glob('*.txt')

pp '*' * 40
# 递归遍历路径下的txt文件
pp Pathname.new(path).glob('**/*.txt')

#输出结果:
[#<Pathname:/Users/yutangzhao/Movies/Ruby/hang.txt>,
 #<Pathname:/Users/yutangzhao/Movies/Ruby/.DS_Store>,
 #<Pathname:/Users/yutangzhao/Movies/Ruby/Test>,
 #<Pathname:/Users/yutangzhao/Movies/Ruby/yang>,
 #<Pathname:/Users/yutangzhao/Movies/Ruby/main.rb>,
 #<Pathname:/Users/yutangzhao/Movies/Ruby/cat.json>,
 #<Pathname:/Users/yutangzhao/Movies/Ruby/yang.yml>,
 #<Pathname:/Users/yutangzhao/Movies/Ruby/yang.json>,
 #<Pathname:/Users/yutangzhao/Movies/Ruby/hang.yml>,
 #<Pathname:/Users/yutangzhao/Movies/Ruby/.bash_profile>]
"****************************************"
[#<Pathname:hang.txt>,
 #<Pathname:.DS_Store>,
 #<Pathname:Test>,
 #<Pathname:yang>,
 #<Pathname:main.rb>,
 #<Pathname:cat.json>,
 #<Pathname:yang.yml>,
 #<Pathname:yang.json>,
 #<Pathname:hang.yml>,
 #<Pathname:.bash_profile>]
"****************************************"
[#<Pathname:/Users/yutangzhao/Movies/Ruby/hang.txt>]
"****************************************"
[#<Pathname:/Users/yutangzhao/Movies/Ruby/hang.txt>,
 #<Pathname:/Users/yutangzhao/Movies/Ruby/yang/yang.txt>]