ruby

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Ruby Development Skill

Ruby开发技能

Purpose

用途

This skill provides comprehensive guidance for Ruby development, covering language fundamentals, object-oriented design, error handling, performance optimization, and modern Ruby (3.x+) features. It synthesizes knowledge from Ruby internals, best practices, and official documentation to help Claude write idiomatic, maintainable, and performant Ruby code.
本技能为Ruby开发提供全面指导,涵盖语言基础、面向对象设计、错误处理、性能优化以及现代Ruby(3.x及以上)特性。它整合了Ruby内部机制、最佳实践和官方文档的知识,帮助Claude编写符合Ruby风格、可维护且高性能的代码。

When to Use This Skill

何时使用本技能

Use this skill when:
  • Writing or reviewing Ruby code
  • Debugging Ruby applications
  • Optimizing Ruby performance
  • Implementing object-oriented designs
  • Handling errors and exceptions
  • Working with Ruby's standard library
  • Using modern Ruby features (pattern matching, types, fibers, ractors)
  • Building Rails applications or Ruby gems
在以下场景使用本技能:
  • 编写或评审Ruby代码
  • 调试Ruby应用
  • 优化Ruby性能
  • 实现面向对象设计
  • 处理错误与异常
  • 使用Ruby标准库
  • 使用现代Ruby特性(模式匹配、类型、Fibers、Ractors)
  • 构建Rails应用或Ruby gems

Ruby Philosophy and Core Principles

Ruby设计理念与核心原则

Matz's Design Philosophy

Matz的设计哲学

Ruby is designed to make programmers happy. It prioritizes:
  1. Developer Productivity - Write less code to accomplish more
  2. Readability - Code should read like natural language
  3. Flexibility - Multiple ways to accomplish tasks (TMTOWTDI - There's More Than One Way To Do It)
  4. Object-Oriented Everything - Everything is an object, including primitives
  5. Duck Typing - "If it walks like a duck and quacks like a duck, it's a duck"
Ruby的设计目标是让程序员感到愉悦。它优先考虑:
  1. 开发者生产力 - 用更少的代码完成更多工作
  2. 可读性 - 代码应像自然语言一样易读
  3. 灵活性 - 完成任务的方式不止一种(TMTOWTDI - There's More Than One Way To Do It)
  4. 万物皆对象 - 所有事物都是对象,包括基本类型
  5. 鸭子类型 - "如果它走起来像鸭子,叫起来像鸭子,那它就是鸭子"

Ruby's Core Characteristics

Ruby的核心特性

ruby
undefined
ruby
undefined

Everything is an object

Everything is an object

5.times { puts "Hello" } # Integer is an object "hello".upcase # String is an object nil.class # => NilClass
5.times { puts "Hello" } # Integer is an object "hello".upcase # String is an object nil.class # => NilClass

Blocks are first-class citizens

Blocks are first-class citizens

[1, 2, 3].map { |n| n * 2 } # => [2, 4, 6]
[1, 2, 3].map { |n| n * 2 } # => [2, 4, 6]

Open classes - can modify any class

Open classes - can modify any class

class String def shout "#{upcase}!" end end
"hello".shout # => "HELLO!"
class String def shout "#{upcase}!" end end
"hello".shout # => "HELLO!"

Duck typing - focus on behavior, not type

Duck typing - focus on behavior, not type

def process(thing) thing.call if thing.respond_to?(:call) end
undefined
def process(thing) thing.call if thing.respond_to?(:call) end
undefined

Object-Oriented Design in Ruby

Ruby中的面向对象设计

The Ruby Object Model

Ruby对象模型

Understanding Ruby's object model is crucial for effective programming:
ruby
undefined
理解Ruby的对象模型是高效编程的关键:
ruby
undefined

Class hierarchy

Class hierarchy

class Animal def speak "Some sound" end end
class Dog < Animal def speak "Woof!" end end
class Animal def speak "Some sound" end end
class Dog < Animal def speak "Woof!" end end

Every class is an instance of Class

Every class is an instance of Class

Dog.class # => Class Dog.superclass # => Animal Animal.superclass # => Object Object.superclass # => BasicObject
Dog.class # => Class Dog.superclass # => Animal Animal.superclass # => Object Object.superclass # => BasicObject

Singleton methods (eigenclass/metaclass)

Singleton methods (eigenclass/metaclass)

dog = Dog.new def dog.name "Buddy" end
dog.name # => "Buddy" Dog.new.name # NoMethodError
undefined
dog = Dog.new def dog.name "Buddy" end
dog.name # => "Buddy" Dog.new.name # NoMethodError
undefined

Composition Over Inheritance

组合优于继承

Prefer composition and modules over deep inheritance hierarchies:
ruby
undefined
优先使用组合和模块,而非深层继承体系:
ruby
undefined

❌ Bad: Deep inheritance

❌ 不良实践:深层继承

class Vehicle end
class LandVehicle < Vehicle end
class Car < LandVehicle end
class SportsCar < Car end
class Vehicle end
class LandVehicle < Vehicle end
class Car < LandVehicle end
class SportsCar < Car end

✅ Good: Composition with modules

✅ 良好实践:使用模块进行组合

module Drivable def drive "Driving..." end end
module Flyable def fly "Flying..." end end
class Car include Drivable end
class Plane include Flyable include Drivable # Can taxi on ground end
undefined
module Drivable def drive "Driving..." end end
module Flyable def fly "Flying..." end end
class Car include Drivable end
class Plane include Flyable include Drivable # 可在地面滑行 end
undefined

Single Responsibility Principle

单一职责原则

Each class should have one reason to change:
ruby
undefined
每个类应该只有一个引起变化的原因:
ruby
undefined

❌ Bad: Multiple responsibilities

❌ 不良实践:多职责

class User def save # Database logic end
def send_email # Email logic end
def generate_report # Report logic end end
class User def save # 数据库逻辑 end
def send_email # 邮件逻辑 end
def generate_report # 报表逻辑 end end

✅ Good: Separate concerns

✅ 良好实践:分离关注点

class User def save UserRepository.new.save(self) end end
class UserMailer def send_welcome_email(user) # Email logic end end
class UserReportGenerator def generate(user) # Report logic end end
undefined
class User def save UserRepository.new.save(self) end end
class UserMailer def send_welcome_email(user) # 邮件逻辑 end end
class UserReportGenerator def generate(user) # 报表逻辑 end end
undefined

Dependency Injection

依赖注入

Inject dependencies rather than hardcoding them:
ruby
undefined
注入依赖而非硬编码:
ruby
undefined

❌ Bad: Hard dependency

❌ 不良实践:硬依赖

class OrderProcessor def process(order) PaymentGateway.new.charge(order.amount) EmailService.new.send_confirmation(order) end end
class OrderProcessor def process(order) PaymentGateway.new.charge(order.amount) EmailService.new.send_confirmation(order) end end

✅ Good: Dependency injection

✅ 良好实践:依赖注入

class OrderProcessor def initialize(payment_gateway: PaymentGateway.new, email_service: EmailService.new) @payment_gateway = payment_gateway @email_service = email_service end
def process(order) @payment_gateway.charge(order.amount) @email_service.send_confirmation(order) end end
undefined
class OrderProcessor def initialize(payment_gateway: PaymentGateway.new, email_service: EmailService.new) @payment_gateway = payment_gateway @email_service = email_service end
def process(order) @payment_gateway.charge(order.amount) @email_service.send_confirmation(order) end end
undefined

Law of Demeter (Principle of Least Knowledge)

迪米特法则(最少知识原则)

Avoid reaching through multiple objects:
ruby
undefined
避免链式调用多个对象:
ruby
undefined

❌ Bad: Train wreck

❌ 不良实践:调用链混乱

customer.orders.last.line_items.first.price
customer.orders.last.line_items.first.price

✅ Good: Delegate or encapsulate

✅ 良好实践:委托或封装

class Customer def last_order_first_item_price orders.last&.first_item_price end end
class Order def first_item_price line_items.first&.price end end
customer.last_order_first_item_price
undefined
class Customer def last_order_first_item_price orders.last&.first_item_price end end
class Order def first_item_price line_items.first&.price end end
customer.last_order_first_item_price
undefined

Error Handling and Exceptions

错误处理与异常

The Exception Hierarchy

异常层级

Exception
├── NoMemoryError
├── ScriptError
│   ├── LoadError
│   ├── NotImplementedError
│   └── SyntaxError
├── SignalException
│   └── Interrupt
├── StandardError (Default rescue catches this)
│   ├── ArgumentError
│   ├── IOError
│   │   └── EOFError
│   ├── IndexError
│   ├── LocalJumpError
│   ├── NameError
│   │   └── NoMethodError
│   ├── RangeError
│   ├── RegexpError
│   ├── RuntimeError (Default raise creates this)
│   ├── SecurityError
│   ├── SystemCallError
│   ├── ThreadError
│   ├── TypeError
│   └── ZeroDivisionError
├── SystemExit
└── SystemStackError
Exception
├── NoMemoryError
├── ScriptError
│   ├── LoadError
│   ├── NotImplementedError
│   └── SyntaxError
├── SignalException
│   └── Interrupt
├── StandardError (默认rescue捕获此类)
│   ├── ArgumentError
│   ├── IOError
│   │   └── EOFError
│   ├── IndexError
│   ├── LocalJumpError
│   ├── NameError
│   │   └── NoMethodError
│   ├── RangeError
│   ├── RegexpError
│   ├── RuntimeError (默认raise创建此类)
│   ├── SecurityError
│   ├── SystemCallError
│   ├── ThreadError
│   ├── TypeError
│   └── ZeroDivisionError
├── SystemExit
└── SystemStackError

Exception Handling Best Practices

异常处理最佳实践

1. Exceptions Should Be Exceptional

1. 异常应用于异常场景

Use exceptions for exceptional cases, not control flow:
ruby
undefined
仅在异常情况下使用异常,而非控制流程:
ruby
undefined

❌ Bad: Using exceptions for control flow

❌ 不良实践:用异常做控制流程

def find_user(id) user = User.find(id) rescue ActiveRecord::RecordNotFound nil end
def find_user(id) user = User.find(id) rescue ActiveRecord::RecordNotFound nil end

✅ Good: Use explicit checks

✅ 良好实践:使用显式检查

def find_user(id) User.find_by(id: id) end
undefined
def find_user(id) User.find_by(id: id) end
undefined

2. Rescue Specific Exceptions

2. 捕获特定异常

Always rescue specific exceptions, never bare rescue:
ruby
undefined
始终捕获特定异常,不要使用裸rescue:
ruby
undefined

❌ Bad: Catches everything, including SystemExit

❌ 不良实践:捕获所有异常,包括SystemExit

begin dangerous_operation rescue

Too broad!

end
begin dangerous_operation rescue

范围过广!

end

✅ Good: Rescue specific exceptions

✅ 良好实践:捕获特定异常

begin dangerous_operation rescue NetworkError, TimeoutError => e logger.error("Network issue: #{e.message}") retry_operation end
undefined
begin dangerous_operation rescue NetworkError, TimeoutError => e logger.error("Network issue: #{e.message}") retry_operation end
undefined

3. Fail Fast, Fail Loudly

3. 快速失败,明确报错

Let errors propagate unless you can handle them meaningfully:
ruby
undefined
除非能有意义地处理错误,否则让错误向上传播:
ruby
undefined

❌ Bad: Swallowing exceptions

❌ 不良实践:吞噬异常

def process_data(data) result = parse(data) rescue => e nil # Silent failure! end
def process_data(data) result = parse(data) rescue => e nil # 静默失败! end

✅ Good: Let it fail or handle meaningfully

✅ 良好实践:让错误传播或进行有意义的处理

def process_data(data) parse(data) rescue ParseError => e logger.error("Failed to parse data: #{e.message}") raise # Re-raise to propagate end
undefined
def process_data(data) parse(data) rescue ParseError => e logger.error("Failed to parse data: #{e.message}") raise # 重新抛出以传播错误 end
undefined

4. Use ensure for Cleanup

4. 使用ensure进行清理

Always use
ensure
for cleanup code:
ruby
undefined
始终使用
ensure
执行清理代码:
ruby
undefined

✅ Proper resource management

✅ 正确的资源管理

def process_file(filename) file = File.open(filename) process(file) ensure file&.close end
def process_file(filename) file = File.open(filename) process(file) ensure file&.close end

Better: Use blocks that auto-close

更优方式:使用自动关闭的块

def process_file(filename) File.open(filename) do |file| process(file) end # Automatically closed end
undefined
def process_file(filename) File.open(filename) do |file| process(file) end # 自动关闭文件 end
undefined

5. Custom Exceptions for Domain Logic

5. 为领域逻辑创建自定义异常

Create custom exceptions for your domain:
ruby
undefined
为业务领域创建自定义异常:
ruby
undefined

Define custom exceptions

定义自定义异常

class PaymentError < StandardError; end class InsufficientFundsError < PaymentError; end class InvalidCardError < PaymentError; end
class PaymentError < StandardError; end class InsufficientFundsError < PaymentError; end class InvalidCardError < PaymentError; end

Use them meaningfully

有意义地使用它们

def charge_card(card, amount) raise InvalidCardError, "Card expired" if card.expired? raise InsufficientFundsError if balance < amount
process_charge(card, amount) end
def charge_card(card, amount) raise InvalidCardError, "Card expired" if card.expired? raise InsufficientFundsError if balance < amount
process_charge(card, amount) end

Caller can handle appropriately

调用方可针对性处理

begin charge_card(card, 100) rescue InsufficientFundsError => e notify_user("Insufficient funds") rescue InvalidCardError => e notify_user("Please update your card") rescue PaymentError => e

Catch all payment errors

logger.error("Payment failed: #{e.message}") end
undefined
begin charge_card(card, 100) rescue InsufficientFundsError => e notify_user("余额不足") rescue InvalidCardError => e notify_user("请更新您的银行卡信息") rescue PaymentError => e

捕获所有支付相关错误

logger.error("Payment failed: #{e.message}") end
undefined

6. The Weirich raise/fail Convention

6. Weirich的raise/fail约定

Use
fail
for exceptions you expect to be rescued,
raise
for re-raising:
ruby
def process_order(order)
  fail ArgumentError, "Order cannot be nil" if order.nil?

  begin
    payment_gateway.charge(order)
  rescue PaymentError => e
    logger.error("Payment failed: #{e.message}")
    raise  # Re-raise with raise
  end
end
使用
fail
表示预期会被捕获的异常,使用
raise
表示重新抛出异常:
ruby
def process_order(order)
  fail ArgumentError, "Order cannot be nil" if order.nil?

  begin
    payment_gateway.charge(order)
  rescue PaymentError => e
    logger.error("Payment failed: #{e.message}")
    raise  # 使用raise重新抛出
  end
end

7. Provide Context in Exceptions

7. 在异常中提供上下文信息

Include helpful information in exception messages:
ruby
undefined
在异常消息中包含有用的信息:
ruby
undefined

❌ Bad: Vague message

❌ 不良实践:模糊的消息

raise "Invalid input"
raise "Invalid input"

✅ Good: Descriptive message with context

✅ 良好实践:带有上下文的描述性消息

raise ArgumentError, "Expected positive integer for age, got: #{age.inspect}"
undefined
raise ArgumentError, "Expected positive integer for age, got: #{age.inspect}"
undefined

Alternative Error Handling Patterns

替代错误处理模式

Result Objects

结果对象

Return result objects instead of raising exceptions:
ruby
class Result
  attr_reader :value, :error

  def initialize(value: nil, error: nil)
    @value = value
    @error = error
  end

  def success?
    error.nil?
  end

  def failure?
    !success?
  end
end

def divide(a, b)
  return Result.new(error: "Division by zero") if b.zero?
  Result.new(value: a / b)
end

result = divide(10, 2)
if result.success?
  puts result.value
else
  puts "Error: #{result.error}"
end
返回结果对象而非抛出异常:
ruby
class Result
  attr_reader :value, :error

  def initialize(value: nil, error: nil)
    @value = value
    @error = error
  end

  def success?
    error.nil?
  end

  def failure?
    !success?
  end
end

def divide(a, b)
  return Result.new(error: "Division by zero") if b.zero?
  Result.new(value: a / b)
end

result = divide(10, 2)
if result.success?
  puts result.value
else
  puts "Error: #{result.error}"
end

Caller-Supplied Fallback Strategy

调用方提供的回退策略

Let callers define error handling:
ruby
def fetch_user(id, &fallback)
  User.find(id)
rescue ActiveRecord::RecordNotFound => e
  fallback ? fallback.call(e) : raise
end
让调用方定义错误处理逻辑:
ruby
def fetch_user(id, &fallback)
  User.find(id)
rescue ActiveRecord::RecordNotFound => e
  fallback ? fallback.call(e) : raise
end

Usage

使用示例

user = fetch_user(999) { |e| User.new(name: "Guest") }
undefined
user = fetch_user(999) { |e| User.new(name: "Guest") }
undefined

Ruby Performance and Optimization

Ruby性能与优化

Understanding Ruby's VM (YARV)

理解Ruby虚拟机(YARV)

Ruby 3.x uses YARV (Yet Another Ruby VM) with JIT compilation:
ruby
undefined
Ruby 3.x使用YARV(Yet Another Ruby VM)并支持JIT编译:
ruby
undefined

Enable JIT (YJIT in Ruby 3.1+)

启用JIT(Ruby 3.1+为YJIT)

Run with: ruby --yjit your_script.rb

运行方式:ruby --yjit your_script.rb

Check JIT status

检查JIT状态

puts "JIT enabled: #{defined?(RubyVM::YJIT)}"
puts "JIT enabled: #{defined?(RubyVM::YJIT)}"

Profile JIT compilation

分析JIT编译情况

RubyVM::YJIT.runtime_stats if defined?(RubyVM::YJIT)
undefined
RubyVM::YJIT.runtime_stats if defined?(RubyVM::YJIT)
undefined

Memory Management and Garbage Collection

内存管理与垃圾回收

Ruby uses generational garbage collection:
ruby
undefined
Ruby使用分代垃圾回收机制:
ruby
undefined

Check GC stats

查看GC统计信息

GC.stat
GC.stat

=> {:count=>23, :heap_allocated_pages=>145, ...}

=> {:count=>23, :heap_allocated_pages=>145, ...}

Manual GC control (rarely needed)

手动控制GC(很少需要)

GC.disable # Disable GC temporarily
GC.disable # 临时禁用GC

... do intensive work

... 执行密集型工作

GC.enable GC.start # Force GC
GC.enable GC.start # 强制触发GC

Monitor object allocations

监控对象分配

before = GC.stat(:total_allocated_objects)
before = GC.stat(:total_allocated_objects)

... your code

... 你的代码

after = GC.stat(:total_allocated_objects) puts "Allocated: #{after - before} objects"
undefined
after = GC.stat(:total_allocated_objects) puts "Allocated: #{after - before} objects"
undefined

Performance Best Practices

性能最佳实践

1. Avoid Creating Unnecessary Objects

1. 避免创建不必要的对象

ruby
undefined
ruby
undefined

❌ Bad: Creates many string objects

❌ 不良实践:创建大量字符串对象

1000.times do |i| "User #{i}" # New string each time end
1000.times do |i| "User #{i}" # 每次创建新字符串 end

✅ Good: Reuse strings with interpolation

✅ 良好实践:使用插值复用字符串

template = "User %d" 1000.times do |i| template % i end
template = "User %d" 1000.times do |i| template % i end

✅ Even better: Use frozen strings

✅ 更优方式:使用冻结字符串

MESSAGE = "Processing".freeze
undefined
MESSAGE = "Processing".freeze
undefined

2. Use Symbols for Repeated Strings

2. 对重复字符串使用符号

ruby
undefined
ruby
undefined

❌ Bad: Creates new string objects

❌ 不良实践:创建新字符串对象

hash = { "name" => "John", "age" => 30 }
hash = { "name" => "John", "age" => 30 }

✅ Good: Symbols are immutable and reused

✅ 良好实践:符号是不可变且可复用的

hash = { name: "John", age: 30 }
undefined
hash = { name: "John", age: 30 }
undefined

3. Prefer Enumerable Methods Over Loops

3. 优先使用Enumerable方法而非循环

ruby
undefined
ruby
undefined

❌ Bad: Manual loop

❌ 不良实践:手动循环

result = [] array.each do |item| result << item * 2 if item > 0 end
result = [] array.each do |item| result << item * 2 if item > 0 end

✅ Good: Chained enumerable methods

✅ 良好实践:链式调用Enumerable方法

result = array.select { |item| item > 0 } .map { |item| item * 2 }
result = array.select { |item| item > 0 } .map { |item| item * 2 }

✅ Even better: Single pass with each_with_object

✅ 更优方式:使用each_with_object单次遍历

result = array.each_with_object([]) do |item, acc| acc << item * 2 if item > 0 end
undefined
result = array.each_with_object([]) do |item, acc| acc << item * 2 if item > 0 end
undefined

4. Use Lazy Enumerables for Large Collections

4. 对大型集合使用惰性枚举

ruby
undefined
ruby
undefined

❌ Bad: Creates intermediate arrays

❌ 不良实践:创建中间数组

(1..1_000_000).select { |n| n.even? } .map { |n| n * 2 } .first(10)
(1..1_000_000).select { |n| n.even? } .map { |n| n * 2 } .first(10)

✅ Good: Lazy evaluation

✅ 良好实践:惰性求值

(1..1_000_000).lazy .select { |n| n.even? } .map { |n| n * 2 } .first(10)
undefined
(1..1_000_000).lazy .select { |n| n.even? } .map { |n| n * 2 } .first(10)
undefined

5. Cache Expensive Computations

5. 缓存昂贵的计算结果

ruby
undefined
ruby
undefined

❌ Bad: Recomputes every time

❌ 不良实践:每次都重新计算

class User def full_name "#{first_name} #{last_name}".strip end end
class User def full_name "#{first_name} #{last_name}".strip end end

✅ Good: Memoization

✅ 良好实践:记忆化(Memoization)

class User def full_name @full_name ||= "#{first_name} #{last_name}".strip end end
class User def full_name @full_name ||= "#{first_name} #{last_name}".strip end end

⚠️ Careful with nil/false values

⚠️ 注意nil/false值的情况

def expensive_check return @result if defined?(@result) @result = compute_result end
undefined
def expensive_check return @result if defined?(@result) @result = compute_result end
undefined

Modern Ruby Features (3.x+)

现代Ruby特性(3.x+)

Pattern Matching (Ruby 2.7+)

模式匹配(Ruby 2.7+)

ruby
undefined
ruby
undefined

Basic pattern matching

基础模式匹配

case [1, 2, 3] in [a, b, c] puts "#{a}, #{b}, #{c}" end
case [1, 2, 3] in [a, b, c] puts "#{a}, #{b}, #{c}" end

Hash patterns

Hash模式

case { name: "John", age: 30 } in { name: "John", age: age } puts "John is #{age}" in { name:, age: } # Variable punning puts "#{name} is #{age}" end
case { name: "John", age: 30 } in { name: "John", age: age } puts "John is #{age}" in { name:, age: } # 变量简写 puts "#{name} is #{age}" end

Array patterns with rest

带剩余元素的数组模式

case [1, 2, 3, 4, 5] in [first, *rest, last] puts "First: #{first}, Last: #{last}, Rest: #{rest}" end
case [1, 2, 3, 4, 5] in [first, *rest, last] puts "First: #{first}, Last: #{last}, Rest: #{rest}" end

Rightward assignment (Ruby 3.0+)

右向赋值(Ruby 3.0+)

{ name: "John", age: 30 } => { name:, age: } puts name # => "John"
{ name: "John", age: 30 } => { name:, age: } puts name # => "John"

Guard clauses

守卫子句

case value in String => s if s.length > 10 puts "Long string: #{s}" in String => s puts "Short string: #{s}" end
undefined
case value in String => s if s.length > 10 puts "Long string: #{s}" in String => s puts "Short string: #{s}" end
undefined

Endless Method Definition (Ruby 3.0+)

无限方法定义(Ruby 3.0+)

ruby
undefined
ruby
undefined

Traditional

传统写法

def square(x) x * x end
def square(x) x * x end

Endless method (for simple one-liners)

无限方法(适用于简单单行方法)

def square(x) = x * x def full_name = "#{first_name} #{last_name}" def admin? = role == "admin"
undefined
def square(x) = x * x def full_name = "#{first_name} #{last_name}" def admin? = role == "admin"
undefined

Numbered Parameters (Ruby 2.7+)

编号参数(Ruby 2.7+)

ruby
undefined
ruby
undefined

Traditional block parameters

传统块参数

[1, 2, 3].map { |n| n * 2 }
[1, 2, 3].map { |n| n * 2 }

Numbered parameters

编号参数

[1, 2, 3].map { _1 * 2 }
[1, 2, 3].map { _1 * 2 }

Multiple numbered parameters

多个编号参数

hash.map { [_1, _2 * 2] }
undefined
hash.map { [_1, _2 * 2] }
undefined

Rightward Assignment (Ruby 3.0+)

右向赋值(Ruby 3.0+)

ruby
undefined
ruby
undefined

Traditional assignment

传统赋值

result = compute_value() puts result
result = compute_value() puts result

Rightward assignment (useful in method chains)

右向赋值(在方法链中很有用)

compute_value() => result puts result
compute_value() => result puts result

Useful for debugging

用于调试

calculate_price.tap { p _1 } => price
undefined
calculate_price.tap { p _1 } => price
undefined

Ractors (Ruby 3.0+) - True Parallelism

Ractors(Ruby 3.0+)- 真正的并行性

ruby
undefined
ruby
undefined

Create parallel-safe ractor

创建并行安全的Ractor

r = Ractor.new do received = Ractor.receive received * 2 end
r.send(21) r.take # => 42
r = Ractor.new do received = Ractor.receive received * 2 end
r.send(21) r.take # => 42

Multiple ractors

多个Ractors

results = 4.times.map do |i| Ractor.new(i) do |n| # Heavy computation (1..1000000).reduce(:+) + n end end
results.map(&:take) # Runs in parallel
undefined
results = 4.times.map do |i| Ractor.new(i) do |n| # 繁重计算 (1..1000000).reduce(:+) + n end end
results.map(&:take) # 并行运行
undefined

Typed Ruby with RBS (Ruby 3.0+)

使用RBS的类型化Ruby(Ruby 3.0+)

ruby
undefined
ruby
undefined

Define types in .rbs files

在.rbs文件中定义类型

user.rbs

user.rbs

class User attr_reader name: String attr_reader age: Integer
def initialize: (name: String, age: Integer) -> void def adult?: () -> bool end
class User attr_reader name: String attr_reader age: Integer
def initialize: (name: String, age: Integer) -> void def adult?: () -> bool end

Use TypeProf to generate signatures

使用TypeProf生成签名

$ typeprof user.rb

$ typeprof user.rb

Validate with Steep or RBS

使用Steep或RBS进行验证

$ steep check

$ steep check

undefined
undefined

Fiber Scheduler (Ruby 3.0+) - Non-blocking I/O

Fiber调度器(Ruby 3.0+)- 非阻塞I/O

ruby
require 'async'
ruby
require 'async'

Async execution with fibers

使用Fibers进行异步执行

Async do Async do puts "Task 1 start" sleep 2 puts "Task 1 end" end
Async do puts "Task 2 start" sleep 1 puts "Task 2 end" end end
Async do Async do puts "Task 1 start" sleep 2 puts "Task 1 end" end
Async do puts "Task 2 start" sleep 1 puts "Task 2 end" end end

Both tasks run concurrently

两个任务并发运行

undefined
undefined

Ruby Standard Library Essentials

Ruby标准库要点

Working with Collections

集合操作

ruby
undefined
ruby
undefined

Array operations

数组操作

arr = [1, 2, 3, 4, 5]
arr.first(2) # => [1, 2] arr.last(2) # => [4, 5] arr.sample # Random element arr.shuffle # Randomize order arr.rotate(2) # => [3, 4, 5, 1, 2] arr.combination(2).to_a # All 2-element combinations arr.permutation(2).to_a # All 2-element permutations
arr = [1, 2, 3, 4, 5]
arr.first(2) # => [1, 2] arr.last(2) # => [4, 5] arr.sample # 随机元素 arr.shuffle # 随机排序 arr.rotate(2) # => [3, 4, 5, 1, 2] arr.combination(2).to_a # 所有2元素组合 arr.permutation(2).to_a # 所有2元素排列

Hash operations

哈希操作

hash = { a: 1, b: 2, c: 3 }
hash.fetch(:d, 0) # => 0 (default value) hash.dig(:nested, :key) # Safe nested access hash.transform_values(&:to_s) # => { a: "1", b: "2", c: "3" } hash.slice(:a, :b) # => { a: 1, b: 2 } hash.merge(d: 4) # Non-destructive merge
hash = { a: 1, b: 2, c: 3 }
hash.fetch(:d, 0) # => 0(默认值) hash.dig(:nested, :key) # 安全的嵌套访问 hash.transform_values(&:to_s) # => { a: "1", b: "2", c: "3" } hash.slice(:a, :b) # => { a: 1, b: 2 } hash.merge(d: 4) # 非破坏性合并

Set operations

集合操作

require 'set' s1 = Set[1, 2, 3] s2 = Set[2, 3, 4]
s1 | s2 # Union => #<Set: {1, 2, 3, 4}> s1 & s2 # Intersection => #<Set: {2, 3}> s1 - s2 # Difference => #<Set: {1}>
undefined
require 'set' s1 = Set[1, 2, 3] s2 = Set[2, 3, 4]
s1 | s2 # 并集 => #<Set: {1, 2, 3, 4}> s1 & s2 # 交集 => #<Set: {2, 3}> s1 - s2 # 差集 => #<Set: {1}>
undefined

String Manipulation

字符串操作

ruby
undefined
ruby
undefined

String methods

字符串方法

str = " Hello, World! "
str.strip # => "Hello, World!" str.split(", ") # => ["Hello", "World!"] str.gsub("World", "Ruby") # => " Hello, Ruby! " str.scan(/\w+/) # => ["Hello", "World"] str.start_with?("Hello") # => false (has spaces) str.include?("World") # => true
str = " Hello, World! "
str.strip # => "Hello, World!" str.split(", ") # => ["Hello", "World!"] str.gsub("World", "Ruby") # => " Hello, Ruby! " str.scan(/\w+/) # => ["Hello", "World"] str.start_with?("Hello") # => false(包含空格) str.include?("World") # => true

String interpolation

字符串插值

name = "John" age = 30 "#{name} is #{age}" # => "John is 30" "2 + 2 = #{2 + 2}" # => "2 + 2 = 4"
name = "John" age = 30 "#{name} is #{age}" # => "John is 30" "2 + 2 = #{2 + 2}" # => "2 + 2 = 4"

Heredocs

heredoc

text = <<~TEXT This is a heredoc. Indentation is removed. Very useful for multi-line strings. TEXT
text = <<~TEXT This is a heredoc. Indentation is removed. Very useful for multi-line strings. TEXT

Frozen strings (immutable)

冻结字符串(不可变)

CONSTANT = "immutable".freeze
CONSTANT = "immutable".freeze

Or with magic comment:

或使用魔法注释:

frozen_string_literal: true

frozen_string_literal: true

undefined
undefined

File I/O

文件I/O

ruby
undefined
ruby
undefined

Reading files

读取文件

content = File.read("file.txt") lines = File.readlines("file.txt")
content = File.read("file.txt") lines = File.readlines("file.txt")

Block-based reading (auto-closes)

基于块的读取(自动关闭)

File.open("file.txt") do |file| file.each_line do |line| puts line end end
File.open("file.txt") do |file| file.each_line do |line| puts line end end

Writing files

写入文件

File.write("output.txt", "Hello, World!")
File.open("output.txt", "w") do |file| file.puts "Line 1" file.puts "Line 2" end
File.write("output.txt", "Hello, World!")
File.open("output.txt", "w") do |file| file.puts "Line 1" file.puts "Line 2" end

File operations

文件操作

File.exist?("file.txt") File.directory?("path") File.size("file.txt") File.mtime("file.txt") # Modification time
File.exist?("file.txt") File.directory?("path") File.size("file.txt") File.mtime("file.txt") # 修改时间

Directory operations

目录操作

Dir.glob("**/*.rb") # Find all Ruby files recursively Dir.foreach("path") { |file| puts file } Dir.mkdir("new_dir")
undefined
Dir.glob("**/*.rb") # 递归查找所有Ruby文件 Dir.foreach("path") { |file| puts file } Dir.mkdir("new_dir")
undefined

Regular Expressions

正则表达式

ruby
undefined
ruby
undefined

Pattern matching

模式匹配

text = "Hello, my email is john@example.com"
text = "Hello, my email is john@example.com"

Match operator

匹配操作符

text =~ /\w+@\w+.\w+/ # => 18 (match position)
text =~ /\w+@\w+.\w+/ # => 18(匹配位置)

Match method

匹配方法

match = text.match(/(\w+)@(\w+).(\w+)/) match[0] # => "john@example.com" match[1] # => "john" match[2] # => "example"
match = text.match(/(\w+)@(\w+).(\w+)/) match[0] # => "john@example.com" match[1] # => "john" match[2] # => "example"

Named captures

命名捕获

match = text.match(/(?<user>\w+)@(?<domain>\w+).(?<tld>\w+)/) match[:user] # => "john" match[:domain] # => "example"
match = text.match(/(?<user>\w+)@(?<domain>\w+).(?<tld>\w+)/) match[:user] # => "john" match[:domain] # => "example"

Scan for all matches

扫描所有匹配项

emails = text.scan(/\w+@\w+.\w+/)
emails = text.scan(/\w+@\w+.\w+/)

Replace with regex

使用正则替换

text.gsub(/\b\w{4}\b/, "****") # Mask 4-letter words
undefined
text.gsub(/\b\w{4}\b/, "****") # 掩码4字母单词
undefined

Testing Ruby Code

Ruby代码测试

Minitest (Standard Library)

Minitest(标准库)

ruby
require 'minitest/autorun'

class UserTest < Minitest::Test
  def setup
    @user = User.new(name: "John", age: 30)
  end

  def test_adult_with_age_over_18
    assert @user.adult?
  end

  def test_name_is_capitalized
    assert_equal "John", @user.name
  end

  def test_invalid_age_raises_error
    assert_raises(ArgumentError) do
      User.new(name: "John", age: -5)
    end
  end

  def teardown
    # Cleanup if needed
  end
end
ruby
require 'minitest/autorun'

class UserTest < Minitest::Test
  def setup
    @user = User.new(name: "John", age: 30)
  end

  def test_adult_with_age_over_18
    assert @user.adult?
  end

  def test_name_is_capitalized
    assert_equal "John", @user.name
  end

  def test_invalid_age_raises_error
    assert_raises(ArgumentError) do
      User.new(name: "John", age: -5)
    end
  end

  def teardown
    # 如有需要进行清理
  end
end

RSpec (Popular Testing Framework)

RSpec(流行的测试框架)

ruby
require 'rspec'

RSpec.describe User do
  let(:user) { User.new(name: "John", age: 30) }

  describe '#adult?' do
    context 'when age is over 18' do
      it 'returns true' do
        expect(user.adult?).to be true
      end
    end

    context 'when age is under 18' do
      let(:user) { User.new(name: "Jane", age: 15) }

      it 'returns false' do
        expect(user.adult?).to be false
      end
    end
  end

  describe '#initialize' do
    it 'raises error for negative age' do
      expect { User.new(name: "John", age: -5) }
        .to raise_error(ArgumentError, /negative age/)
    end
  end

  describe '#name' do
    it 'returns capitalized name' do
      expect(user.name).to eq("John")
    end
  end
end
ruby
require 'rspec'

RSpec.describe User do
  let(:user) { User.new(name: "John", age: 30) }

  describe '#adult?' do
    context 'when age is over 18' do
      it 'returns true' do
        expect(user.adult?).to be true
      end
    end

    context 'when age is under 18' do
      let(:user) { User.new(name: "Jane", age: 15) }

      it 'returns false' do
        expect(user.adult?).to be false
      end
    end
  end

  describe '#initialize' do
    it 'raises error for negative age' do
      expect { User.new(name: "John", age: -5) }
        .to raise_error(ArgumentError, /negative age/)
    end
  end

  describe '#name' do
    it 'returns capitalized name' do
      expect(user.name).to eq("John")
    end
  end
end

Testing Best Practices

测试最佳实践

ruby
undefined
ruby
undefined

1. Use descriptive test names

1. 使用描述性的测试名称

def test_user_is_adult_when_age_is_over_18

Clear what is being tested

end
def test_user_is_adult_when_age_is_over_18

清晰表明测试内容

end

2. Arrange-Act-Assert pattern

2. Arrange-Act-Assert模式

def test_order_total

Arrange

order = Order.new order.add_item(item: "Book", price: 10) order.add_item(item: "Pen", price: 2)

Act

total = order.total

Assert

assert_equal 12, total end
def test_order_total

准备(Arrange)

order = Order.new order.add_item(item: "Book", price: 10) order.add_item(item: "Pen", price: 2)

执行(Act)

total = order.total

断言(Assert)

assert_equal 12, total end

3. Test one thing per test

3. 每个测试只测一件事

❌ Bad: Tests multiple things

❌ 不良实践:测试多个内容

def test_user assert user.valid? assert_equal "John", user.name assert_equal 30, user.age end
def test_user assert user.valid? assert_equal "John", user.name assert_equal 30, user.age end

✅ Good: Separate tests

✅ 良好实践:拆分测试

def test_user_is_valid assert user.valid? end
def test_user_name assert_equal "John", user.name end
def test_user_is_valid assert user.valid? end
def test_user_name assert_equal "John", user.name end

4. Use fixtures/factories for test data

4. 使用fixtures/factories生成测试数据

factories.rb

factories.rb

FactoryBot.define do factory :user do name { "John" } age { 30 } email { "john@example.com" } end end
FactoryBot.define do factory :user do name { "John" } age { 30 } email { "john@example.com" } end end

In tests

在测试中使用

user = create(:user) user_attrs = attributes_for(:user)
undefined
user = create(:user) user_attrs = attributes_for(:user)
undefined

Common Ruby Patterns and Idioms

常见Ruby模式与惯用语法

Method Chaining (Fluent Interface)

方法链式调用(流畅接口)

ruby
class QueryBuilder
  def initialize
    @conditions = []
    @order = nil
  end

  def where(condition)
    @conditions << condition
    self  # Return self for chaining
  end

  def order(field)
    @order = field
    self
  end

  def to_sql
    sql = "SELECT * FROM users"
    sql += " WHERE #{@conditions.join(' AND ')}" unless @conditions.empty?
    sql += " ORDER BY #{@order}" if @order
    sql
  end
end
ruby
class QueryBuilder
  def initialize
    @conditions = []
    @order = nil
  end

  def where(condition)
    @conditions << condition
    self  # 返回self以支持链式调用
  end

  def order(field)
    @order = field
    self
  end

  def to_sql
    sql = "SELECT * FROM users"
    sql += " WHERE #{@conditions.join(' AND ')}" unless @conditions.empty?
    sql += " ORDER BY #{@order}" if @order
    sql
  end
end

Usage

使用示例

query = QueryBuilder.new .where("age > 18") .where("active = true") .order("name") .to_sql
undefined
query = QueryBuilder.new .where("age > 18") .where("active = true") .order("name") .to_sql
undefined

Builder Pattern

构建器模式

ruby
class UserBuilder
  def initialize
    @user = User.new
  end

  def with_name(name)
    @user.name = name
    self
  end

  def with_email(email)
    @user.email = email
    self
  end

  def build
    @user
  end
end
ruby
class UserBuilder
  def initialize
    @user = User.new
  end

  def with_name(name)
    @user.name = name
    self
  end

  def with_email(email)
    @user.email = email
    self
  end

  def build
    @user
  end
end

Usage

使用示例

user = UserBuilder.new .with_name("John") .with_email("john@example.com") .build
undefined
user = UserBuilder.new .with_name("John") .with_email("john@example.com") .build
undefined

Null Object Pattern

空对象模式

ruby
class NullUser
  def name
    "Guest"
  end

  def admin?
    false
  end

  def logged_in?
    false
  end
end

class UserSession
  def current_user
    @current_user || NullUser.new
  end
end
ruby
class NullUser
  def name
    "Guest"
  end

  def admin?
    false
  end

  def logged_in?
    false
  end
end

class UserSession
  def current_user
    @current_user || NullUser.new
  end
end

Usage - no nil checks needed

使用示例 - 无需检查nil

session = UserSession.new puts session.current_user.name # "Guest" instead of error
undefined
session = UserSession.new puts session.current_user.name # 输出"Guest"而非报错
undefined

Strategy Pattern

策略模式

ruby
undefined
ruby
undefined

Define strategies

定义策略

class CreditCardPayment def process(amount) # Credit card logic end end
class PayPalPayment def process(amount) # PayPal logic end end
class CreditCardPayment def process(amount) # 信用卡支付逻辑 end end
class PayPalPayment def process(amount) # PayPal支付逻辑 end end

Use strategy

使用策略

class Order def initialize(payment_strategy) @payment_strategy = payment_strategy end
def checkout(amount) @payment_strategy.process(amount) end end
class Order def initialize(payment_strategy) @payment_strategy = payment_strategy end
def checkout(amount) @payment_strategy.process(amount) end end

Usage

使用示例

order = Order.new(CreditCardPayment.new) order.checkout(100)
undefined
order = Order.new(CreditCardPayment.new) order.checkout(100)
undefined

Observer Pattern

观察者模式

ruby
require 'observer'

class Order
  include Observable

  attr_reader :status

  def status=(new_status)
    @status = new_status
    changed
    notify_observers(self)
  end
end

class Logger
  def update(order)
    puts "Order status changed to: #{order.status}"
  end
end

class Emailer
  def update(order)
    puts "Sending email about: #{order.status}"
  end
end
ruby
require 'observer'

class Order
  include Observable

  attr_reader :status

  def status=(new_status)
    @status = new_status
    changed
    notify_observers(self)
  end
end

class Logger
  def update(order)
    puts "Order status changed to: #{order.status}"
  end
end

class Emailer
  def update(order)
    puts "Sending email about: #{order.status}"
  end
end

Usage

使用示例

order = Order.new order.add_observer(Logger.new) order.add_observer(Emailer.new) order.status = "shipped"
undefined
order = Order.new order.add_observer(Logger.new) order.add_observer(Emailer.new) order.status = "shipped"
undefined

Ruby Code Style and Conventions

Ruby代码风格与规范

Naming Conventions

命名规范

ruby
undefined
ruby
undefined

Classes and Modules: PascalCase

类与模块:PascalCase

class UserAccount end
module PaymentProcessing end
class UserAccount end
module PaymentProcessing end

Methods and Variables: snake_case

方法与变量:snake_case

def calculate_total_price total_amount = 0 end
def calculate_total_price total_amount = 0 end

Constants: SCREAMING_SNAKE_CASE

常量:SCREAMING_SNAKE_CASE

MAX_RETRIES = 3 DEFAULT_TIMEOUT = 30
MAX_RETRIES = 3 DEFAULT_TIMEOUT = 30

Predicate methods: end with ?

判断方法:以?结尾

def valid? errors.empty? end
def admin? role == 'admin' end
def valid? errors.empty? end
def admin? role == 'admin' end

Dangerous methods: end with !

危险方法:以!结尾

def save! # Raises exception on failure raise "Invalid" unless valid? persist end
def downcase! # Mutates the object @value = @value.downcase end
undefined
def save! # 失败时抛出异常 raise "Invalid" unless valid? persist end
def downcase! # 修改对象本身 @value = @value.downcase end
undefined

Code Organization

代码组织

ruby
undefined
ruby
undefined

Class organization

类的组织顺序

class User

1. Extend and include statements

extend SomeModule include AnotherModule

2. Constants

MAX_NAME_LENGTH = 100

3. Attribute macros

attr_reader :id attr_accessor :name

4. Class methods

def self.find(id) # ... end

5. Initialization

def initialize(name) @name = name end

6. Public instance methods

def full_name "#{first_name} #{last_name}" end

7. Protected methods

protected
def internal_helper # ... end

8. Private methods

private
def calculate_something # ... end end
undefined
class User

1. 扩展与包含语句

extend SomeModule include AnotherModule

2. 常量

MAX_NAME_LENGTH = 100

3. 属性宏

attr_reader :id attr_accessor :name

4. 类方法

def self.find(id) # ... end

5. 初始化方法

def initialize(name) @name = name end

6. 公共实例方法

def full_name "#{first_name} #{last_name}" end

7. 受保护方法

protected
def internal_helper # ... end

8. 私有方法

private
def calculate_something # ... end end
undefined

Ruby Style Guidelines

Ruby风格指南

ruby
undefined
ruby
undefined

Use 2 spaces for indentation

使用2个空格缩进

def method_name if condition do_something end end
def method_name if condition do_something end end

Avoid ternary operators for multi-line

避免多行三元运算符

❌ Bad

❌ 不良实践

result = some_long_condition ? long_true_value : long_false_value
result = some_long_condition ? long_true_value : long_false_value

✅ Good

✅ 良好实践

result = if some_long_condition long_true_value else long_false_value end
result = if some_long_condition long_true_value else long_false_value end

Use %w for word arrays

使用%w定义单词数组

❌ Bad

❌ 不良实践

STATES = ['draft', 'published', 'archived']
STATES = ['draft', 'published', 'archived']

✅ Good

✅ 良好实践

STATES = %w[draft published archived]
STATES = %w[draft published archived]

Use symbols for hash keys

使用符号作为哈希键

❌ Bad (when strings aren't needed)

❌ 不良实践(不需要字符串时)

{ 'name' => 'John', 'age' => 30 }
{ 'name' => 'John', 'age' => 30 }

✅ Good

✅ 良好实践

{ name: 'John', age: 30 }
{ name: 'John', age: 30 }

Use guard clauses

使用守卫子句

❌ Bad

❌ 不良实践

def process(value) if value if value.valid? # ... main logic end end end
def process(value) if value if value.valid? # ... 主逻辑 end end end

✅ Good

✅ 良好实践

def process(value) return unless value return unless value.valid?

... main logic

end
def process(value) return unless value return unless value.valid?

... 主逻辑

end

Avoid returning from ensure

避免在ensure中返回值

❌ Bad - return value is ignored

❌ 不良实践 - 返回值会被忽略

def bad_example return 42 ensure return 0 # This overrides! end
def bad_example return 42 ensure return 0 # 这会覆盖之前的返回值! end

✅ Good

✅ 良好实践

def good_example result = 42 ensure cleanup end
undefined
def good_example result = 42 ensure cleanup end
undefined

Debugging Ruby Code

Ruby代码调试

Using pry for Debugging

使用pry进行调试

ruby
require 'pry'

def complex_method(data)
  result = transform(data)
  binding.pry  # Execution pauses here
  result * 2
end
ruby
require 'pry'

def complex_method(data)
  result = transform(data)
  binding.pry  # 执行在此处暂停
  result * 2
end

In pry session:

在pry会话中:

- ls: List available methods

- ls: 列出可用方法

- show-method method_name: Show method source

- show-method method_name: 显示方法源码

- cd object: Enter object context

- cd object: 进入对象上下文

- whereami: Show context

- whereami: 显示当前上下文

- continue: Resume execution

- continue: 恢复执行

undefined
undefined

Using ruby/debug (Ruby 3.1+)

使用ruby/debug(Ruby 3.1+)

ruby
require 'debug'

def calculate(x, y)
  debugger  # Execution pauses here
  result = x + y
  result
end
ruby
require 'debug'

def calculate(x, y)
  debugger  # 执行在此处暂停
  result = x + y
  result
end

Commands:

命令:

- step: Step into

- step: 单步进入

- next: Step over

- next: 单步跳过

- continue: Resume

- continue: 恢复执行

- info: Show information

- info: 显示信息

- break: Set breakpoint

- break: 设置断点

undefined
undefined

Logging Best Practices

日志最佳实践

ruby
require 'logger'

logger = Logger.new(STDOUT)
logger.level = Logger::INFO
ruby
require 'logger'

logger = Logger.new(STDOUT)
logger.level = Logger::INFO

Different log levels

不同日志级别

logger.debug("Detailed debug information") logger.info("Informational messages") logger.warn("Warning messages") logger.error("Error messages") logger.fatal("Fatal errors")
logger.debug("Detailed debug information") logger.info("Informational messages") logger.warn("Warning messages") logger.error("Error messages") logger.fatal("Fatal errors")

Structured logging

结构化日志

logger.info("User logged in") do { user_id: 123, ip: "192.168.1.1" } end
undefined
logger.info("User logged in") do { user_id: 123, ip: "192.168.1.1" } end
undefined

Concurrency and Threading

并发与线程

Thread Basics

线程基础

ruby
undefined
ruby
undefined

Create threads

创建线程

threads = 3.times.map do |i| Thread.new(i) do |thread_num| puts "Thread #{thread_num} starting" sleep 1 puts "Thread #{thread_num} done" end end
threads = 3.times.map do |i| Thread.new(i) do |thread_num| puts "Thread #{thread_num} starting" sleep 1 puts "Thread #{thread_num} done" end end

Wait for all threads

等待所有线程完成

threads.each(&:join)
threads.each(&:join)

Thread-local variables

线程局部变量

Thread.current[:user_id] = 123 Thread.current[:user_id] # => 123
undefined
Thread.current[:user_id] = 123 Thread.current[:user_id] # => 123
undefined

Thread Safety

线程安全

ruby
undefined
ruby
undefined

❌ Bad: Race condition

❌ 不良实践:竞态条件

class Counter def initialize @count = 0 end
def increment @count += 1 # Not atomic! end end
class Counter def initialize @count = 0 end
def increment @count += 1 # 非原子操作! end end

✅ Good: Thread-safe with mutex

✅ 良好实践:使用互斥锁保证线程安全

class Counter def initialize @count = 0 @mutex = Mutex.new end
def increment @mutex.synchronize do @count += 1 end end end
class Counter def initialize @count = 0 @mutex = Mutex.new end
def increment @mutex.synchronize do @count += 1 end end end

✅ Better: Use Concurrent::AtomicFixnum

✅ 更优方式:使用Concurrent::AtomicFixnum

require 'concurrent'
counter = Concurrent::AtomicFixnum.new(0) counter.increment
undefined
require 'concurrent'
counter = Concurrent::AtomicFixnum.new(0) counter.increment
undefined

Ractors for Parallelism (Ruby 3.0+)

使用Ractors实现并行(Ruby 3.0+)

ruby
undefined
ruby
undefined

True parallel execution

真正的并行执行

def parallel_map(array, &block) ractors = array.map do |item| Ractor.new(item, block) do |value, transform| transform.call(value) end end
ractors.map(&:take) end
def parallel_map(array, &block) ractors = array.map do |item| Ractor.new(item, block) do |value, transform| transform.call(value) end end
ractors.map(&:take) end

Usage

使用示例

results = parallel_map([1, 2, 3, 4]) { |n| n * 2 }
results = parallel_map([1, 2, 3, 4]) { |n| n * 2 }

=> [2, 4, 6, 8]

=> [2, 4, 6, 8]

undefined
undefined

Metaprogramming

元编程

method_missing

method_missing

ruby
class DynamicAccessor
  def initialize(data)
    @data = data
  end

  def method_missing(method, *args)
    if @data.key?(method)
      @data[method]
    else
      super
    end
  end

  def respond_to_missing?(method, include_private = false)
    @data.key?(method) || super
  end
end
ruby
class DynamicAccessor
  def initialize(data)
    @data = data
  end

  def method_missing(method, *args)
    if @data.key?(method)
      @data[method]
    else
      super
    end
  end

  def respond_to_missing?(method, include_private = false)
    @data.key?(method) || super
  end
end

Usage

使用示例

obj = DynamicAccessor.new(name: "John", age: 30) obj.name # => "John" obj.age # => 30
undefined
obj = DynamicAccessor.new(name: "John", age: 30) obj.name # => "John" obj.age # => 30
undefined

define_method

define_method

ruby
class Model
  %w[name email age].each do |attr|
    define_method(attr) do
      instance_variable_get("@#{attr}")
    end

    define_method("#{attr}=") do |value|
      instance_variable_set("@#{attr}", value)
    end
  end
end
ruby
class Model
  %w[name email age].each do |attr|
    define_method(attr) do
      instance_variable_get("@#{attr}")
    end

    define_method("#{attr}=") do |value|
      instance_variable_set("@#{attr}", value)
    end
  end
end

Creates name, name=, email, email=, age, age= methods

生成name, name=, email, email=, age, age=方法

undefined
undefined

class_eval and instance_eval

class_eval和instance_eval

ruby
undefined
ruby
undefined

class_eval: Evaluates in class context

class_eval: 在类上下文中执行

String.class_eval do def shout upcase + "!" end end
"hello".shout # => "HELLO!"
String.class_eval do def shout upcase + "!" end end
"hello".shout # => "HELLO!"

instance_eval: Evaluates in instance context

instance_eval: 在实例上下文中执行

str = "hello" str.instance_eval do def custom_method "Custom: #{self}" end end
str.custom_method # => "Custom: hello"
undefined
str = "hello" str.instance_eval do def custom_method "Custom: #{self}" end end
str.custom_method # => "Custom: hello"
undefined

Memory and Performance Profiling

内存与性能分析

Benchmark Module

Benchmark模块

ruby
require 'benchmark'

n = 1_000_000
Benchmark.bm(20) do |x|
  x.report("Array#each:") do
    arr = []
    n.times { |i| arr << i }
  end

  x.report("Array#map:") do
    (0...n).map { |i| i }
  end

  x.report("Array.new:") do
    Array.new(n) { |i| i }
  end
end
ruby
require 'benchmark'

n = 1_000_000
Benchmark.bm(20) do |x|
  x.report("Array#each:") do
    arr = []
    n.times { |i| arr << i }
  end

  x.report("Array#map:") do
    (0...n).map { |i| i }
  end

  x.report("Array.new:") do
    Array.new(n) { |i| i }
  end
end

Memory Profiler

内存分析器

ruby
require 'memory_profiler'

report = MemoryProfiler.report do
  # Code to profile
  1000.times { "string" + "concatenation" }
end

report.pretty_print
ruby
require 'memory_profiler'

report = MemoryProfiler.report do
  # 要分析的代码
  1000.times { "string" + "concatenation" }
end

report.pretty_print

Ruby Profiler

Ruby分析器

ruby
require 'ruby-prof'

result = RubyProf.profile do
  # Code to profile
  10_000.times { expensive_operation }
end

printer = RubyProf::FlatPrinter.new(result)
printer.print(STDOUT)
ruby
require 'ruby-prof'

result = RubyProf.profile do
  # 要分析的代码
  10_000.times { expensive_operation }
end

printer = RubyProf::FlatPrinter.new(result)
printer.print(STDOUT)

Common Pitfalls and How to Avoid Them

常见陷阱与规避方法

1. Modifying Collections During Iteration

1. 迭代时修改集合

ruby
undefined
ruby
undefined

❌ Bad: Modifies while iterating

❌ 不良实践:迭代时修改集合

array = [1, 2, 3, 4, 5] array.each do |item| array.delete(item) if item.even? # Unpredictable! end
array = [1, 2, 3, 4, 5] array.each do |item| array.delete(item) if item.even? # 结果不可预测! end

✅ Good: Use reject or delete_if

✅ 良好实践:使用reject或delete_if

array.reject! { |item| item.even? }
array.reject! { |item| item.even? }

Or

array.delete_if { |item| item.even? }
undefined
array.delete_if { |item| item.even? }
undefined

2. Unintended Global Variable Modification

2. 意外修改全局变量

ruby
undefined
ruby
undefined

❌ Bad: Global variable

❌ 不良实践:全局变量

$user_count = 0
$user_count = 0

✅ Good: Class or instance variable

✅ 良好实践:类变量或实例变量

class UserCounter @count = 0
class << self attr_accessor :count end end
undefined
class UserCounter @count = 0
class << self attr_accessor :count end end
undefined

3. String Concatenation in Loops

3. 循环中的字符串拼接

ruby
undefined
ruby
undefined

❌ Bad: Creates many string objects

❌ 不良实践:创建大量字符串对象

result = "" 1000.times { |i| result += "#{i} " }
result = "" 1000.times { |i| result += "#{i} " }

✅ Good: Use array join

✅ 良好实践:使用数组join

result = 1000.times.map { |i| "#{i} " }.join
result = 1000.times.map { |i| "#{i} " }.join

✅ Better: Use string builder

✅ 更优方式:使用字符串构建器

result = String.new 1000.times { |i| result << "#{i} " }
undefined
result = String.new 1000.times { |i| result << "#{i} " }
undefined

4. Forgetting to Return Values

4. 忘记返回值

ruby
undefined
ruby
undefined

❌ Bad: No explicit return

❌ 不良实践:无显式返回

def calculate total = items.sum

Implicitly returns total, but unclear

end
def calculate total = items.sum

隐式返回total,但不够清晰

end

✅ Good: Explicit return for clarity

✅ 良好实践:显式返回以提升清晰度

def calculate total = items.sum return total end
def calculate total = items.sum return total end

✅ Best: Last expression is return value

✅ 最佳实践:最后一个表达式即为返回值

def calculate items.sum end
undefined
def calculate items.sum end
undefined

Framework-Specific Guidance

框架专属指导

Rails-Specific Best Practices

Rails专属最佳实践

ruby
undefined
ruby
undefined

Use scopes for reusable queries

使用作用域定义可复用查询

class User < ApplicationRecord scope :active, -> { where(active: true) } scope :recent, -> { where('created_at > ?', 1.week.ago) } end
class User < ApplicationRecord scope :active, -> { where(active: true) } scope :recent, -> { where('created_at > ?', 1.week.ago) } end

Use concerns for shared behavior

使用concerns共享行为

module Timestampable extend ActiveSupport::Concern
included do before_save :update_timestamp end
def update_timestamp self.updated_at = Time.current end end
module Timestampable extend ActiveSupport::Concern
included do before_save :update_timestamp end
def update_timestamp self.updated_at = Time.current end end

Use strong parameters

使用强参数

class UsersController < ApplicationController def create @user = User.new(user_params) # ... end
private
def user_params params.require(:user).permit(:name, :email, :age) end end
class UsersController < ApplicationController def create @user = User.new(user_params) # ... end
private
def user_params params.require(:user).permit(:name, :email, :age) end end

Eager loading to avoid N+1 queries

预加载避免N+1查询

❌ Bad: N+1 query

❌ 不良实践:N+1查询

users = User.all users.each { |user| puts user.posts.count }
users = User.all users.each { |user| puts user.posts.count }

✅ Good: Eager load

✅ 良好实践:预加载

users = User.includes(:posts).all users.each { |user| puts user.posts.count }
undefined
users = User.includes(:posts).all users.each { |user| puts user.posts.count }
undefined

Quick Reference Commands

快速参考命令

bash
undefined
bash
undefined

Ruby version

Ruby版本

ruby -v
ruby -v

Run Ruby file

运行Ruby文件

ruby script.rb
ruby script.rb

Interactive Ruby (IRB)

交互式Ruby(IRB)

irb
irb

Execute inline Ruby

执行单行Ruby代码

ruby -e "puts 'Hello, World!'"
ruby -e "puts 'Hello, World!'"

Check syntax without executing

检查语法不执行

ruby -c script.rb
ruby -c script.rb

Run with warnings

带警告运行

ruby -w script.rb
ruby -w script.rb

Install gem

安装gem

gem install gem_name
gem install gem_name

List installed gems

列出已安装的gem

gem list
gem list

Update gems

更新gem

gem update
gem update

Bundle install (Rails)

安装依赖(Rails)

bundle install
bundle install

Run tests

运行测试

ruby test/my_test.rb rake test rspec spec/
ruby test/my_test.rb rake test rspec spec/

Ruby documentation

Ruby文档

ri String#upcase ri Array
ri String#upcase ri Array

Generate documentation

生成文档

rdoc yard doc
undefined
rdoc yard doc
undefined

Resources and Further Learning

资源与进阶学习

Summary

总结

Ruby is designed for developer happiness and productivity. When writing Ruby code:
  1. Write readable code - Code is read more than it's written
  2. Follow conventions - Consistency helps teams collaborate
  3. Test thoroughly - Tests give confidence in refactoring
  4. Handle errors explicitly - Fail fast and provide context
  5. Optimize when necessary - Profile before optimizing
  6. Embrace Ruby's features - Use blocks, modules, and metaprogramming appropriately
  7. Stay current - Ruby 3.x brings significant improvements
Remember: Ruby rewards simple, expressive code that clearly communicates intent.
Ruby的设计目标是提升开发者的幸福感与生产力。编写Ruby代码时:
  1. 编写易读代码 - 代码被阅读的次数远多于编写次数
  2. 遵循规范 - 一致性有助于团队协作
  3. 充分测试 - 测试为重构提供信心
  4. 显式处理错误 - 快速失败并提供上下文
  5. 必要时再优化 - 先分析再优化
  6. 拥抱Ruby特性 - 合理使用块、模块与元编程
  7. 保持更新 - Ruby 3.x带来了显著改进
请记住:Ruby推崇简洁、富有表现力且能清晰传达意图的代码。