基础数据类型及逻辑运算
ruby
puts "Hello, World!"
# 局部变量(小写或下划线开头)
name = "Alice"
age = 25
# 常量(首字母大写,约定全大写)
PI = 3.14159
MAX_USERS = 100
puts name # => "Alice"
puts PI # => 3.14159
# 字符串及插值
str1 = "Hello"
str2 = 'World'
puts "#{str1}, #{str2}!" # => "Hello, World!"
num1 = 42 # Integer
num2 = 3.14 # Float
puts num1 + num2 # => 45.14
puts false && true # => false
age = 25
puts "可以喝酒" if age >= 18 && age < 60
puts false || true # => true
weather = "rainy"
puts "带伞" if weather == "rainy" || weather == "snowy"
puts !true # => false
puts !false # => true
logged_in = false
puts "请登录" unless logged_in # unless 相当于 if not
控制流
ruby
# if-else
age = 18
if age >= 18
puts "Adult"
else
puts "Child"
end
# 三元运算符
status = age >= 18 ? "Adult" : "Child"
puts status
# while 循环
i = 0
while i < 3
puts i
i += 1
end
# each 迭代(更 Ruby 风格)
(1..5).each do |num|
puts num * 2
end
grade = "B"
case grade
when "A"
puts "Excellent!"
when "B"
puts "Good!"
else
puts "Needs improvement."
end
方法与块
ruby
# 定义方法
def greet(name)
"Hello, #{name}!"
end
# 调用方法
puts greet("Alice") # => "Hello, Alice!"
# 带默认参数的方法
def greet(name = "Stranger")
"Hello, #{name}!"
end
puts greet # => "Hello, Stranger!"
puts greet("Bob") # => "Hello, Bob!"
# 显式返回
def add(a, b)
return a + b
end
# 隐式返回(最后一行表达式的结果)
def multiply(a, b)
a * b
end
puts add(2, 3) # => 5
puts multiply(2, 3) # => 6
# 可变参数
def sum(*numbers)
# inject方法(与reduce方法完全相同)接受初始值(这里是0),对集合中的每个元素执行块中操作,将结果累积起来
numbers.inject(0) { |total, num| total + num }
end
puts sum(1, 2, 3) # => 6
puts sum(4, 5, 6, 7) # => 22
# 单行块用花括号
3.times { puts "Hello" }
# 多行块用do...end
3.times do
puts "Hello"
puts "World"
end
# 带参数的块
[1, 2, 3].each { |num| puts num * 2 }
def my_method
puts "Before block"
# yield调用传入块,这里传入的快就是简单的{ puts "Inside block" },block_given为内置方法判断是否传入块
yield if block_given?
puts "After block"
end
my_method { puts "Inside block" }
# 输出:
# Before block
# Inside block
# After block
def calculate(a, b)
# 使用yield调用传入的块,并将a和b作为参数传递给块
yield(a, b)
end
result = calculate(5, 3) { |x, y| x * y }
puts result # => 15
# 显示接受块参数
# &表示将传入的块转换为一个Proc对象,这个参数必须是方法的最后一个参数,如果没有传入,则block将为nil
def process_items(items, &block)
items.each(&block)
end
process_items([1, 2, 3]) { |n| puts n * 10 }
# 输出:
# 10
# 20
# 30
# 创建Proc对象
# Proc对象是Ruby中可调用的代码块,可以理解为"过程对象"或"可执行代码块"
double = Proc.new { |x| x * 2 }
triple = proc { |x| x * 3 } # proc是Proc.new的简写
puts double.call(5) # => 10
puts triple.call(5) # => 15
# 将Proc作为参数传递
def apply_operation(value, operation)
operation.call(value)
end
puts apply_operation(4, double) # => 8
# 创建lambda
square = lambda { |x| x ** 2 }
cube = ->(x) { x ** 3 } # 另一种lambda语法
puts square.call(3) # => 9
puts cube.call(3) # => 27
# lambda与Proc的区别
def test_lambda
l = lambda { return "lambda" }
l.call
"method"
end
def test_proc
p = Proc.new { return "proc" }
p.call
"method"
end
puts test_lambda # => "method" (lambda的return只从lambda返回)
puts test_proc # => "proc" (proc的return会从包含它的方法返回)
案例应用
ruby
# 案例1: 自定义迭代器
def my_each(array)
i = 0
while i < array.length
yield(array[i]) # 将当前元素传给块
i += 1
end
array
end
my_each([1, 2, 3]) { |n| puts n * 2 }
# 输出:
# 2
# 4
# 6
# 案例2:资源管理
def with_file(file_name, mode)
file = File.open(file_name, mode)
yield(file) if block_given?
ensure
file.close if file
end
with_file("test.txt", "w") do |f|
f.puts "Hello, world!"
end
# 案例3: 回调机制
class Button
def initialize(&on_click)
@on_click = on_click # 将传入的块转换为Proc对象存储
end
def click
@on_click.call if @on_click # 调用存储的Proc对象
end
end
button = Button.new { puts "Button clicked!" }
button.click # => "Button clicked!"
# 案例4:DSL(领域特定语言)
def describe(description, &block)
puts "Description: #{description}"
block.call
end
def it(description, &block)
puts " Test: #{description}"
block.call
end
describe "数学运算" do
it "加法" do
puts " 2 + 2 = #{2 + 2}"
end
it "乘法" do
puts " 3 * 3 = #{3 * 3}"
end
end
# 输出:
# Description: 数学运算
# Test: 加法
# 2 + 2 = 4
# Test: 乘法
# 3 * 3 = 9
类与对象
ruby
class Person
end
person = Person.new
puts person.class # => Person
puts person.object_id # => 输出对象的唯一ID
# 带initialize方法的类
class Person
def initialize(name, age)
@name = name
@age = age
end
end
person = Person.new("张三", 25)
# puts person.name 因为属性没有set所以获取不到
# puts person.age
# 手动定义访问器
class Person
def initialize(name)
@name = name
end
# getter方法
def name
@name
end
# setter方法
def name=(new_name)
@name = new_name
end
end
# 使用attr_*系列方法
p = Person.new("李四")
puts p.name # => "李四"
p.name = "王五"
puts p.name # => "王五"
class Person
attr_reader :name # 只读
attr_writer :age # 只写
attr_accessor :city # 读写
def initialize(name, age, city)
@name = name
@age = age
@city = city
end
end
p = Person.new("赵六", 30, "北京")
puts p.name # => "赵六"
# puts p.age # 会报错,因为没有reader
p.age = 31 # 可以设置
puts p.city # => "北京"
p.city = "上海"
# 类方法与实例方法
class Calculator
# 类方法
def self.description
"这是一个计算器类"
end
# 实例方法
def add(a, b)
a + b
end
end
puts Calculator.description # => "这是一个计算器类"
calc = Calculator.new
puts calc.add(2, 3) # => 5
# 基础继承
class Animal
def speak
"动物叫声"
end
end
class Dog < Animal
def speak
"汪汪汪"
end
end
class Cat < Animal
def speak
"喵喵喵"
end
end
animals = [Animal.new, Dog.new, Cat.new]
animals.each { |a| puts a.speak }
# 输出:
# 动物叫声
# 汪汪汪
# 喵喵喵
# super关键字
class Parent
def greet
"你好,"
end
end
class Child < Parent
def greet
super + "小朋友!"
end
end
puts Child.new.greet # => "你好,小朋友!"
# 模块与混入Mixins
module Swimmable
def swim
"我可以游泳"
end
end
class Fish
include Swimmable
end
class Dog
include Swimmable
end
puts Fish.new.swim # => "我可以游泳"
puts Dog.new.swim # => "我可以游泳"
# 类变量与类实力变量
class MyClass
@@class_var = "类变量"
@class_instance_var = "类实例变量"
def self.show_vars
puts "@@class_var: #{@@class_var}"
puts "@class_instance_var: #{@class_instance_var}"
end
def show_vars
puts "@@class_var: #{@@class_var}"
puts "@class_instance_var: #{@class_instance_var || '未定义'}"
end
end
MyClass.show_vars
# @@class_var: 类变量
# @class_instance_var: 类实例变量
obj = MyClass.new
obj.show_vars
# @@class_var: 类变量
# @class_instance_var: 未定义
# 单例方法
class MyClass
end
obj = MyClass.new
def obj.special_method
"我是这个对象特有的方法"
end
puts obj.special_method # => "我是这个对象特有的方法"
another_obj = MyClass.new
# another_obj.special_method # 会报错,因为只有第一个对象有这个特殊方法
案例应用
ruby
# 银行账户系统
class BankAccount
attr_reader :balance
def initialize(initial_balance = 0)
@balance = initial_balance
end
def deposit(amount)
@balance += amount
puts "存入 #{amount},当前余额 #{@balance}"
end
def withdraw(amount)
if amount <= @balance
@balance -= amount
puts "取出 #{amount},当前余额 #{@balance}"
else
puts "余额不足"
end
end
end
account = BankAccount.new(100)
account.deposit(50) # => 存入 50,当前余额 150
account.withdraw(200) # => 余额不足
account.withdraw(80) # => 取出 80,当前余额 70
# 图书售卖管理
class Product
attr_accessor :name, :price, :quantity
def initialize(name, price, quantity)
@name = name
@price = price
@quantity = quantity
end
def total_value
@price * @quantity
end
def to_s
"#{@name} - 单价: #{@price}元, 库存: #{@quantity}"
end
end
class Book < Product
attr_accessor :author, :isbn
def initialize(name, price, quantity, author, isbn)
super(name, price, quantity)
@author = author
@isbn = isbn
end
def to_s
super + ", 作者: #{@author}, ISBN: #{@isbn}"
end
end
book = Book.new("Ruby编程", 59.99, 10, "松本行弘", "978-7-121-12345-6")
puts book
puts "总价值: #{book.total_value}元"
模块
ruby
# 基本命名空间
module MyMath
PI = 3.14159
def self.circle_area(r)
PI * r**2
end
end
puts MyMath::PI # => 3.14159
puts MyMath.circle_area(5) # => 78.53975
# 嵌套命名空间
module Company
module HR
class Employee
attr_accessor :name
end
end
module Finance
class Payroll
def calculate
"计算工资"
end
end
end
end
emp = Company::HR::Employee.new
emp.name = "张三"
payroll = Company::Finance::Payroll.new
puts payroll.calculate
# 作为Mixins基本混入
module Swimmable
def swim
"我可以游泳"
end
end
class Fish
include Swimmable
end
class Dog
include Swimmable
end
puts Fish.new.swim # => "我可以游泳"
puts Dog.new.swim # => "我可以游泳"
# 作为Mixins多重混入
module Flyable
def fly
"我可以飞"
end
end
module Runnable
def run
"我可以跑"
end
end
class Bird
include Flyable
include Runnable
end
bird = Bird.new
puts bird.fly # => "我可以飞"
puts bird.run # => "我可以跑"
# 使用extend添加类方法
module ClassMethods
def class_method
"这是一个类方法"
end
end
class MyClass
extend ClassMethods
end
puts MyClass.class_method # => "这是一个类方法"
# 同时包含实例方法和类方法
module MyModule
def instance_method
"实例方法"
end
module ClassMethods
def class_method
"类方法"
end
end
def self.included(base)
base.extend(ClassMethods)
end
end
class MyClass
include MyModule
end
puts MyClass.new.instance_method # => "实例方法"
puts MyClass.class_method # => "类方法"
# 模块前置和后置处理
module Loggable
def self.included(base)
puts "#{base} 包含了 #{self}"
end
def self.extended(base)
puts "#{base} 扩展了 #{self}"
end
end
class MyClass
include Loggable # 输出: MyClass 包含了 Loggable
extend Loggable # 输出: MyClass 扩展了 Loggable
end
# 模块函数
module MathUtils
def self.square(x)
x * x
end
module_function
def cube(x)
x * x * x
end
end
puts MathUtils.square(3) # => 9
puts MathUtils.cube(3) # => 27
异常处理
ruby
begin
result = 10 / 0
rescue ZeroDivisionError => e
puts "Error: #{e.message}" # => "Error: divided by 0"
ensure
puts "Cleanup code here"
end