Web 应用开发教程

1. Ruby 简介和特性

1.1 什么是 Ruby?

Ruby 是一种动态、开源的编程语言,以其简洁性和生产力著称。它由 Yukihiro "Matz" Matsumoto 在 1990 年代中期设计,旨在结合多种编程范式的优点。

1.2 Ruby 的特性

  • 简洁性:Ruby 的语法设计简洁,易于阅读和编写。
  • 面向对象:Ruby 是完全面向对象的语言,一切皆对象。
  • 动态类型:变量的类型在运行时确定,增加了灵活性。
  • 丰富的标准库:Ruby 提供了丰富的标准库,涵盖了从文件操作到网络编程的各个方面。

2. 安装 Ruby 和开发环境设置

2.1 安装 Ruby

  • Windows:使用 RubyInstaller (https://rubyinstaller.org/)。
  • macOS:使用 Homebrew (brew install ruby)。
  • Linux:使用包管理器(如 apt-get 或 yum)安装。

2.2 开发环境设置

  • 文本编辑器:推荐使用 VS Code、Sublime Text 或 Atom。
  • 集成开发环境 (IDE):RubyMine 是一个强大的 Ruby IDE。

3. IRB (交互式 Ruby)

3.1 什么是 IRB?

IRB(Interactive Ruby)是一个交互式 Ruby 解释器,允许你在命令行中直接运行 Ruby 代码。

3.2 使用 IRB

$ irb
irb(main):001:0> puts "Hello, World!"
Hello, World!
=> nil

4. 基本语法和数据类型

4.1 基本语法

  • 注释:使用 # 进行单行注释。
  • 多行注释:使用 =begin 和 =end。

4.2 数据类型

  • 数字:整数和浮点数。
  • 字符串:使用单引号或双引号。
  • 布尔值:true 和 false。
  • 数组:有序集合。
  • 哈希:键值对集合。

5. 变量和常量

5.1 变量

变量用于存储数据,使用小写字母或下划线命名。

name = "Alice"
age = 30

5.2 常量

常量使用大写字母命名,一旦赋值后不应更改。

PI = 3.14159

6. 条件语句

6.1 if 语句

if condition
  # code
end

6.2 unless 语句

unless condition
  # code
end

6.3 case 语句

case variable
when value1
  # code
when value2
  # code
else
  # code
end

7. 循环

7.1 while 循环

while condition
  # code
end

7.2 until 循环

until condition
  # code
end

7.3 for 循环

for i in 1..5
  puts i
end

7.4 each 方法

(1..5).each do |i|
  puts i
end

8. 迭代器和块

8.1 迭代器

迭代器是一种方法,用于遍历集合中的元素。

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

8.2 块

块是一段代码,可以传递给方法。

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

9. 方法定义和调用

9.1 方法定义

def greet(name)
  puts "Hello, #{name}!"
end

9.2 方法调用

greet("Alice")

10. 参数和返回值

10.1 参数

方法可以接受参数。

def add(a, b)
  a + b
end

10.2 返回值

方法默认返回最后一行代码的值。

result = add(3, 4)
puts result # 输出 7

11. 块、Proc 和 Lambda

11.1 块

块是一段代码,可以传递给方法。

[1, 2, 3].each { |num| puts num }

11.2 Proc

Proc 是一个对象化的块。

my_proc = Proc.new { |x| puts x }
my_proc.call(5)

11.3 Lambda

Lambda 是另一种块对象化的方式。

my_lambda = lambda { |x| puts x }
my_lambda.call(5)

12. 数组操作

12.1 创建数组

numbers = [1, 2, 3, 4, 5]

12.2 访问元素

puts numbers[0] # 输出 1

12.3 添加元素

numbers << 6

13. 哈希表操作

13.1 创建哈希

person = { name: "Alice", age: 30 }

13.2 访问值

puts person[:name] # 输出 "Alice"

13.3 添加键值对

person[:city] = "New York"

14. 枚举模块和方法

14.1 枚举模块

枚举模块提供了许多用于遍历集合的方法。

[1, 2, 3].each { |num| puts num }

14.2 常用方法

  • map:返回一个新的数组,包含每个元素的处理结果。
  • select:返回一个新的数组,包含满足条件的元素。

15. 字符串操作和插值

15.1 字符串操作

greeting = "Hello"
name = "Alice"
puts greeting + " " + name # 输出 "Hello Alice"

15.2 字符串插值

puts "#{greeting} #{name}" # 输出 "Hello Alice"

16. 符号的使用和优势

16.1 符号

符号是不可变的字符串,通常用作哈希的键。

person = { :name => "Alice", :age => 30 }

16.2 优势

  • 符号比字符串更高效,因为它们是不可变的。
  • 符号在哈希中作为键时,性能更好。

17. 类和对象

17.1 定义类

class Person
  def initialize(name, age)
    @name = name
    @age = age
  end

  def greet
    puts "Hello, my name is #{@name} and I am #{@age} years old."
  end
end

17.2 创建对象

alice = Person.new("Alice", 30)
alice.greet

18. 继承和模块

18.1 继承

class Student < Person
  def initialize(name, age, grade)
    super(name, age)
    @grade = grade
  end

  def display_grade
    puts "Grade: #{@grade}"
  end
end

18.2 模块

模块是一种组织代码的方式,可以包含方法和常量。

module Greeting
  def greet
    puts "Hello!"
  end
end

class Person
  include Greeting
end

person = Person.new
person.greet

19. 方法可见性

19.1 公共方法

class Person
  def greet
    puts "Hello!"
  end
end

19.2 私有方法

class Person
  private

  def secret_method
    puts "This is a secret!"
  end
end

20. 类方法和实例方法

20.1 类方法

class Person
  def self.create_person(name, age)
    Person.new(name, age)
  end
end

20.2 实例方法

class Person
  def greet
    puts "Hello!"
  end
end

21. 元编程基础

21.1 动态方法定义

class Person
  define_method :greet do |name|
    puts "Hello, #{name}!"
  end
end

21.2 钩子方法

class Person
  def self.inherited(subclass)
    puts "#{subclass} inherits from Person"
  end
end

22. 模块定义和使用

22.1 定义模块

module Greeting
  def greet
    puts "Hello!"
  end
end

22.2 使用模块

class Person
  include Greeting
end

23. 混入 (Mixin) 技术

23.1 混入

混入是一种将模块的功能添加到类中的技术。

module Greeting
  def greet
    puts "Hello!"
  end
end

class Person
  include Greeting
end

24. 命名空间

24.1 命名空间

命名空间用于避免类名冲突。

module MyApp
  class Person
    def greet
      puts "Hello!"
    end
  end
end

25. 文件读写

25.1 读取文件

File.open("example.txt", "r") do |file|
  puts file.read
end

25.2 写入文件

File.open("example.txt", "w") do |file|
  file.write("Hello, World!")
end

26. 目录操作

26.1 创建目录

Dir.mkdir("new_directory")

26.2 列出目录内容

Dir.entries(".").each { |entry| puts entry }

27. 序列化和反序列化

27.1 序列化

require 'json'

person = { name: "Alice", age: 30 }
File.open("person.json", "w") do |file|
  file.write(person.to_json)
end

27.2 反序列化

require 'json'

person_json = File.read("person.json")
person = JSON.parse(person_json)
puts person["name"] # 输出 "Alice"

28. 异常类层次结构

28.1 异常类

Ruby 中的异常类继承自 Exception。

begin
  # code that might raise an exception
rescue StandardError => e
  puts "Error: #{e.message}"
end

29. 抛出和捕获异常

29.1 抛出异常

raise "Something went wrong!"

29.2 捕获异常

begin
  raise "Something went wrong!"
rescue => e
  puts "Error: #{e.message}"
end

30. 自定义异常

30.1 定义自定义异常

class MyCustomError < StandardError; end

30.2 使用自定义异常

begin
  raise MyCustomError, "This is a custom error"
rescue MyCustomError => e
  puts "Custom Error: #{e.message}"
end

31. 闭包和作用域

31.1 闭包

闭包是一个可以访问其定义时作用域的代码块。

def create_counter
  count = 0
  lambda { count += 1 }
end

counter = create_counter
puts counter.call # 输出 1
puts counter.call # 输出 2

31.2 作用域

作用域定义了变量的可见性。

x = 10

def my_method
  x = 20
  puts x # 输出 20
end

puts x # 输出 10

32. 元编程技术

32.1 动态方法定义

class Person
  define_method :greet do |name|
    puts "Hello, #{name}!"
  end
end

32.2 钩子方法

class Person
  def self.inherited(subclass)
    puts "#{subclass} inherits from Person"
  end
end

33. 线程基础

33.1 创建线程

thread = Thread.new do
  puts "Hello from a thread!"
end

thread.join

33.2 线程同步

mutex = Mutex.new

thread1 = Thread.new do
  mutex.synchronize do
    puts "Thread 1 is running"
  end
end

thread2 = Thread.new do
  mutex.synchronize do
    puts "Thread 2 is running"
  end
end

thread1.join
thread2.join

34. 纤程 (Fiber)

34.1 纤程

纤程是一种轻量级的线程,允许手动控制执行流程。

fiber = Fiber.new do
  puts "Fiber started"
  Fiber.yield
  puts "Fiber resumed"
end

fiber.resume
fiber.resume

35. RSpec 测试框架

35.1 安装 RSpec

gem install rspec

35.2 编写测试

require 'rspec'

describe "Calculator" do
  it "adds two numbers" do
    expect(1 + 1).to eq(2)
  end
end

36. 测试驱动开发 (TDD)

36.1 TDD 流程

  1. 编写测试。
  2. 运行测试,确保失败。
  3. 编写代码,使测试通过。
  4. 重构代码。

36.2 示例

# calculator_spec.rb
require 'rspec'
require './calculator'

describe Calculator do
  it "adds two numbers" do
    calculator = Calculator.new
    expect(calculator.add(1, 1)).to eq(2)
  end
end

# calculator.rb
class Calculator
  def add(a, b)
    a + b
  end
end

37. 模拟和存根

37.1 模拟

模拟对象用于替换真实对象,以便测试。

require 'rspec'
require 'rspec/mocks'

describe "User" do
  it "sends a welcome email" do
    user = User.new
    allow(user).to receive(:send_email)
    user.send_welcome_email
    expect(user).to have_received(:send_email)
  end
end

37.2 存根

存根用于替换方法的返回值。

require 'rspec'
require 'rspec/mocks'

describe "User" do
  it "gets the user's name" do
    user = User.new
    allow(user).to receive(:name).and_return("Alice")
    expect(user.name).to eq("Alice")
  end
end

38. MVC 架构

38.