Ruby

  1. 1. Ruby 概述
  2. 2. 基础语法
    1. 2.1. 变量和数据类型
    2. 2.2. 控制结构
    3. 2.3. 循环
  3. 3. 面向对象编程
    1. 3.1. 类和对象
    2. 3.2. 继承
    3. 3.3. 模块(Modules)
  4. 4. 方法和块
    1. 4.1. 方法定义
    2. 4.2. 块(Blocks)、Proc 和 Lambda
  5. 5. 常用方法和技巧
    1. 5.1. 数组方法
    2. 5.2. 字符串方法
    3. 5.3. 哈希方法
  6. 6. 异常处理
  7. 7. 文件操作
  8. 8. 总结核心知识要点
    1. 8.1. 语言特性
    2. 8.2. 核心语法示例
      1. 8.2.1. 1. 变量和常量
      2. 8.2.2. 2. 集合操作
      3. 8.2.3. 3. 面向对象
      4. 8.2.4. 4. 模块和混入
      5. 8.2.5. 5. 迭代器和块
    3. 8.3. 常用命令
    4. 8.4. 最佳实践
    5. 8.5. 核心概念
  9. 9. References

Ruby is a dynamic, open source programming language with a focus on simplicity and productivity. It has an elegant syntax that is natural to read and easy to write.

Ruby 概述

Ruby 是一种动态的、面向对象的编程语言,由日本程序员松本行弘(Yukihiro “Matz” Matsumoto)于1995年创建。Ruby 的设计哲学是:

  • 开发者的快乐优先: 让编程变得愉悦
  • 最小惊讶原则: 语言行为符合直觉
  • 多范式编程: 支持面向对象、函数式、命令式等多种编程范式

基础语法

变量和数据类型

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# 变量(无需声明类型)
name = "Alice"
age = 30
pi = 3.14159
is_valid = true

# 常量(首字母大写)
MAX_SIZE = 100
PI = 3.14159

# 符号(Symbol)- 不可变的字符串
status = :active
direction = :north

# 数组
numbers = [1, 2, 3, 4, 5]
mixed = [1, "two", 3.0, :four]

# 哈希(Hash)
person = { name: "Bob", age: 25, city: "NYC" }
legacy_hash = { "name" => "Charlie", "age" => 35 }

# 范围(Range)
range1 = 1..10 # 1 到 10(包含10)
range2 = 1...10 # 1 到 10(不包含10)

控制结构

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
# if/elsif/else
age = 18
if age >= 18
puts "Adult"
elsif age >= 13
puts "Teenager"
else
puts "Child"
end

# 单行 if
puts "Adult" if age >= 18

# unless(if 的反向)
puts "Not adult" unless age >= 18

# case/when
grade = 'B'
case grade
when 'A'
puts "Excellent"
when 'B'
puts "Good"
when 'C'
puts "Average"
else
puts "Need improvement"
end

# 三元运算符
result = age >= 18 ? "Adult" : "Minor"

循环

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
# while 循环
i = 0
while i < 5
puts i
i += 1
end

# until 循环(while 的反向)
i = 0
until i >= 5
puts i
i += 1
end

# for 循环
for i in 0..4
puts i
end

# times 循环
5.times do |i|
puts i
end

# each 遍历数组
[1, 2, 3].each do |num|
puts num
end

# each 遍历哈希
person.each do |key, value|
puts "#{key}: #{value}"
end

# loop 无限循环
loop do
puts "Infinite loop"
break if some_condition
end

面向对象编程

类和对象

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
# 定义类
class Person
# 类变量
@@count = 0

# 属性访问器
attr_accessor :name, :age # 读写
attr_reader :id # 只读
attr_writer :password # 只写

# 初始化方法(构造函数)
def initialize(name, age)
@name = name # 实例变量
@age = age
@id = @@count += 1
end

# 实例方法
def introduce
"Hi, I'm #{@name}, #{@age} years old."
end

# 类方法
def self.total_count
@@count
end

# 私有方法
private

def secret_method
"This is private"
end
end

# 创建对象
person = Person.new("Alice", 30)
puts person.introduce
puts person.name
person.age = 31
puts Person.total_count

继承

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
# 父类
class Animal
attr_accessor :name

def initialize(name)
@name = name
end

def speak
"Some sound"
end
end

# 子类继承
class Dog < Animal
def speak
"Woof!"
end

def fetch
"#{@name} is fetching the ball"
end
end

# 使用 super 调用父类方法
class Cat < Animal
def initialize(name, color)
super(name) # 调用父类的 initialize
@color = color
end

def speak
"Meow!"
end
end

dog = Dog.new("Buddy")
puts dog.speak # "Woof!"
puts dog.fetch # "Buddy is fetching the ball"

模块(Modules)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
# 模块用于命名空间和混入(Mixin)
module Swimmable
def swim
"Swimming..."
end
end

module Flyable
def fly
"Flying..."
end
end

# 混入模块
class Duck
include Swimmable
include Flyable

def quack
"Quack!"
end
end

duck = Duck.new
puts duck.swim # "Swimming..."
puts duck.fly # "Flying..."
puts duck.quack # "Quack!"

# 命名空间
module MyApp
module Models
class User
# User model
end
end
end

user = MyApp::Models::User.new

方法和块

方法定义

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# 基本方法
def greet(name)
"Hello, #{name}!"
end

# 默认参数
def greet(name = "Guest")
"Hello, #{name}!"
end

# 可变参数
def sum(*numbers)
numbers.reduce(0, :+)
end
puts sum(1, 2, 3, 4) # 10

# 关键字参数
def create_user(name:, age:, email: nil)
{ name: name, age: age, email: email }
end
create_user(name: "Alice", age: 30)

# 隐式返回(最后一行表达式)
def add(a, b)
a + b # 自动返回
end

块(Blocks)、Proc 和 Lambda

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# 块(Block)
[1, 2, 3].each { |n| puts n }

[1, 2, 3].each do |n|
puts n * 2
end

# 自定义方法接受块
def my_method
yield if block_given?
end
my_method { puts "Block executed" }

# Proc(可存储的块)
my_proc = Proc.new { |x| x * 2 }
puts my_proc.call(5) # 10

# Lambda(更严格的 Proc)
my_lambda = lambda { |x| x * 2 }
my_lambda = ->(x) { x * 2 } # 简写
puts my_lambda.call(5) # 10

# Lambda 和 Proc 的区别
# 1. Lambda 检查参数数量,Proc 不检查
# 2. Lambda 的 return 只退出 lambda,Proc 的 return 退出包含它的方法

常用方法和技巧

数组方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
arr = [1, 2, 3, 4, 5]

# 遍历和转换
arr.map { |x| x * 2 } # [2, 4, 6, 8, 10]
arr.select { |x| x > 2 } # [3, 4, 5]
arr.reject { |x| x > 2 } # [1, 2]
arr.find { |x| x > 2 } # 3
arr.reduce(0) { |sum, x| sum + x } # 15

# 其他常用方法
arr.first # 1
arr.last # 5
arr.length # 5
arr.empty? # false
arr.include?(3) # true
arr.reverse # [5, 4, 3, 2, 1]
arr.sort # [1, 2, 3, 4, 5]
arr.uniq # 去重

字符串方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
str = "Hello World"

str.upcase # "HELLO WORLD"
str.downcase # "hello world"
str.capitalize # "Hello world"
str.reverse # "dlroW olleH"
str.length # 11
str.split # ["Hello", "World"]
str.include?("World") # true
str.gsub("World", "Ruby") # "Hello Ruby"

# 字符串插值
name = "Alice"
"Hello, #{name}!" # "Hello, Alice!"

# 多行字符串
text = <<~HEREDOC
This is a
multi-line string
with indentation removed
HEREDOC

哈希方法

1
2
3
4
5
6
7
hash = { a: 1, b: 2, c: 3 }

hash.keys # [:a, :b, :c]
hash.values # [1, 2, 3]
hash.has_key?(:a) # true
hash.merge({ d: 4 }) # { a: 1, b: 2, c: 3, d: 4 }
hash.select { |k, v| v > 1 } # { b: 2, c: 3 }

异常处理

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
# 基本异常处理
begin
# 可能抛出异常的代码
result = 10 / 0
rescue ZeroDivisionError => e
puts "Error: #{e.message}"
rescue StandardError => e
puts "Other error: #{e.message}"
else
puts "No errors"
ensure
puts "Always executed"
end

# 抛出异常
def validate_age(age)
raise ArgumentError, "Age must be positive" if age < 0
end

# 自定义异常
class CustomError < StandardError; end

begin
raise CustomError, "Something went wrong"
rescue CustomError => e
puts e.message
end

文件操作

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# 读取文件
content = File.read("file.txt")

# 逐行读取
File.readlines("file.txt").each do |line|
puts line
end

# 写入文件
File.write("file.txt", "Hello, Ruby!")

# 使用块自动关闭文件
File.open("file.txt", "w") do |file|
file.puts "Line 1"
file.puts "Line 2"
end

# 追加内容
File.open("file.txt", "a") do |file|
file.puts "Appended line"
end

# 检查文件存在
File.exist?("file.txt")
File.directory?("path/to/dir")

总结核心知识要点

语言特性

  • 动态类型: 无需声明变量类型,运行时确定
  • 面向对象: 一切皆对象,包括数字、字符串等基本类型
  • 简洁语法: 隐式返回、可选括号、符号表示
  • 块和闭包: 强大的代码块功能,支持 Proc 和 Lambda

核心语法示例

1. 变量和常量

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 局部变量
name = "Ruby"

# 实例变量
@instance_var = "instance"

# 类变量
@@class_var = "class"

# 全局变量
$global_var = "global"

# 常量
CONSTANT = "immutable"

# 符号(不可变字符串)
status = :active

2. 集合操作

1
2
3
4
5
6
7
8
9
10
11
# 数组操作链
result = [1, 2, 3, 4, 5]
.map { |x| x * 2 }
.select { |x| x > 5 }
.reduce(:+)
# result = 18

# 哈希操作
person = { name: "Alice", age: 30 }
person.merge!(city: "NYC")
person.transform_values { |v| v.to_s }

3. 面向对象

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
class BankAccount
attr_reader :balance

def initialize(initial_balance = 0)
@balance = initial_balance
end

def deposit(amount)
@balance += amount if amount > 0
end

def withdraw(amount)
@balance -= amount if amount > 0 && amount <= @balance
end
end

account = BankAccount.new(1000)
account.deposit(500)
account.withdraw(200)

4. 模块和混入

1
2
3
4
5
6
7
8
9
10
11
12
13
module Logging
def log(message)
puts "[#{Time.now}] #{message}"
end
end

class Application
include Logging

def run
log "Application started"
end
end

5. 迭代器和块

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 各种迭代方式
5.times { |i| puts i }
1.upto(5) { |i| puts i }
5.downto(1) { |i| puts i }

# 自定义迭代器
class MyCollection
def initialize(data)
@data = data
end

def each
@data.each { |item| yield item }
end
end

collection = MyCollection.new([1, 2, 3])
collection.each { |item| puts item }

常用命令

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# 运行 Ruby 脚本
ruby script.rb

# 交互式 Ruby(IRB)
irb

# 安装 gem 包
gem install package_name

# 查看已安装的 gem
gem list

# Bundler 管理依赖
bundle install
bundle exec ruby script.rb

# 运行测试
ruby test_file.rb
rake test

最佳实践

  • 遵循 Ruby 风格指南: 使用 2 空格缩进,蛇形命名法
  • 使用符号作为哈希键: { name: "Alice" } 而不是 { "name" => "Alice" }
  • 利用块和迭代器: 避免使用传统 for 循环
  • 使用 attr_accessor: 简化 getter/setter 定义
  • 异常处理: 只捕获需要处理的特定异常
  • 使用 Bundler 管理依赖: 通过 Gemfile 管理项目依赖

核心概念

  • Duck Typing: “如果它走起来像鸭子,叫起来像鸭子,那它就是鸭子”
  • 元编程: Ruby 强大的运行时代码生成能力
  • Mixin: 通过模块实现多重继承效果
  • 开放类: 可以重新打开和修改任何类(包括标准库)
  • 块即闭包: 块可以捕获外部作用域的变量

References