一文速通Ruby语法
基础数据类型及逻辑运算
puts "Hello, World!"# 局部变量(小写或下划线开头)
name = "Alice"
age = 25# 常量(首字母大写,约定全大写)
PI = 3.14159
MAX_USERS = 100puts 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.14puts false && true # => false
age = 25
puts "可以喝酒" if age >= 18 && age < 60puts 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
控制流
# if-else
age = 18
if age >= 18puts "Adult"
elseputs "Child"
end# 三元运算符
status = age >= 18 ? "Adult" : "Child"
puts status# while 循环
i = 0
while i < 3puts ii += 1
end# each 迭代(更 Ruby 风格)
(1..5).each do |num|puts num * 2
endgrade = "B"
case grade
when "A"puts "Excellent!"
when "B"puts "Good!"
elseputs "Needs improvement."
end
方法与块
# 定义方法
def greet(name)"Hello, #{name}!"
end# 调用方法
puts greet("Alice") # => "Hello, Alice!"# 带默认参数的方法
def greet(name = "Stranger")"Hello, #{name}!"
endputs greet # => "Hello, Stranger!"
puts greet("Bob") # => "Hello, Bob!"# 显式返回
def add(a, b)return a + b
end# 隐式返回(最后一行表达式的结果)
def multiply(a, b)a * b
endputs add(2, 3) # => 5
puts multiply(2, 3) # => 6# 可变参数
def sum(*numbers)# inject方法(与reduce方法完全相同)接受初始值(这里是0),对集合中的每个元素执行块中操作,将结果累积起来numbers.inject(0) { |total, num| total + num }
endputs sum(1, 2, 3) # => 6
puts sum(4, 5, 6, 7) # => 22# 单行块用花括号
3.times { puts "Hello" }# 多行块用do...end
3.times doputs "Hello"puts "World"
end# 带参数的块
[1, 2, 3].each { |num| puts num * 2 }def my_methodputs "Before block"# yield调用传入块,这里传入的快就是简单的{ puts "Inside block" },block_given为内置方法判断是否传入块yield if block_given? puts "After block"
endmy_method { puts "Inside block" }# 输出:
# Before block
# Inside block
# After blockdef calculate(a, b)# 使用yield调用传入的块,并将a和b作为参数传递给块yield(a, b)
endresult = calculate(5, 3) { |x, y| x * y }
puts result # => 15# 显示接受块参数
# &表示将传入的块转换为一个Proc对象,这个参数必须是方法的最后一个参数,如果没有传入,则block将为nil
def process_items(items, &block)items.each(&block)
endprocess_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)
endputs 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_lambdal = lambda { return "lambda" }l.call"method"
enddef test_procp = Proc.new { return "proc" }p.call"method"
endputs test_lambda # => "method" (lambda的return只从lambda返回)
puts test_proc # => "proc" (proc的return会从包含它的方法返回)
案例应用
# 案例1: 自定义迭代器
def my_each(array)i = 0while i < array.lengthyield(array[i]) # 将当前元素传给块i += 1endarray
endmy_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?
ensurefile.close if file
endwith_file("test.txt", "w") do |f|f.puts "Hello, world!"
end# 案例3: 回调机制
class Buttondef initialize(&on_click)@on_click = on_click # 将传入的块转换为Proc对象存储enddef click@on_click.call if @on_click # 调用存储的Proc对象end
endbutton = Button.new { puts "Button clicked!" }
button.click # => "Button clicked!"# 案例4:DSL(领域特定语言)
def describe(description, &block)puts "Description: #{description}"block.call
enddef it(description, &block)puts " Test: #{description}"block.call
enddescribe "数学运算" doit "加法" doputs " 2 + 2 = #{2 + 2}"endit "乘法" doputs " 3 * 3 = #{3 * 3}"end
end# 输出:
# Description: 数学运算
# Test: 加法
# 2 + 2 = 4
# Test: 乘法
# 3 * 3 = 9
类与对象
class Person
endperson = Person.new
puts person.class # => Person
puts person.object_id # => 输出对象的唯一ID# 带initialize方法的类
class Persondef initialize(name, age)@name = name@age = ageend
endperson = Person.new("张三", 25)
# puts person.name 因为属性没有set所以获取不到
# puts person.age# 手动定义访问器
class Persondef initialize(name)@name = nameend# getter方法def name@nameend# setter方法def name=(new_name)@name = new_nameend
end# 使用attr_*系列方法
p = Person.new("李四")
puts p.name # => "李四"
p.name = "王五"
puts p.name # => "王五"class Personattr_reader :name # 只读attr_writer :age # 只写attr_accessor :city # 读写def initialize(name, age, city)@name = name@age = age@city = cityend
endp = 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 + bend
endputs Calculator.description # => "这是一个计算器类"
calc = Calculator.new
puts calc.add(2, 3) # => 5# 基础继承
class Animaldef speak"动物叫声"end
endclass Dog < Animaldef speak"汪汪汪"end
endclass Cat < Animaldef speak"喵喵喵"end
endanimals = [Animal.new, Dog.new, Cat.new]
animals.each { |a| puts a.speak }
# 输出:
# 动物叫声
# 汪汪汪
# 喵喵喵# super关键字
class Parentdef greet"你好,"end
endclass Child < Parentdef greetsuper + "小朋友!"end
endputs Child.new.greet # => "你好,小朋友!"# 模块与混入Mixins
module Swimmabledef swim"我可以游泳"end
endclass Fishinclude Swimmable
endclass Doginclude Swimmable
endputs Fish.new.swim # => "我可以游泳"
puts Dog.new.swim # => "我可以游泳"# 类变量与类实力变量
class MyClass@@class_var = "类变量"@class_instance_var = "类实例变量"def self.show_varsputs "@@class_var: #{@@class_var}"puts "@class_instance_var: #{@class_instance_var}"enddef show_varsputs "@@class_var: #{@@class_var}"puts "@class_instance_var: #{@class_instance_var || '未定义'}"end
endMyClass.show_vars
# @@class_var: 类变量
# @class_instance_var: 类实例变量obj = MyClass.new
obj.show_vars
# @@class_var: 类变量
# @class_instance_var: 未定义# 单例方法
class MyClass
endobj = MyClass.newdef obj.special_method"我是这个对象特有的方法"
endputs obj.special_method # => "我是这个对象特有的方法"another_obj = MyClass.new
# another_obj.special_method # 会报错,因为只有第一个对象有这个特殊方法
案例应用
# 银行账户系统
class BankAccountattr_reader :balancedef initialize(initial_balance = 0)@balance = initial_balanceenddef deposit(amount)@balance += amountputs "存入 #{amount},当前余额 #{@balance}"enddef withdraw(amount)if amount <= @balance@balance -= amountputs "取出 #{amount},当前余额 #{@balance}"elseputs "余额不足"endend
endaccount = BankAccount.new(100)
account.deposit(50) # => 存入 50,当前余额 150
account.withdraw(200) # => 余额不足
account.withdraw(80) # => 取出 80,当前余额 70# 图书售卖管理
class Productattr_accessor :name, :price, :quantitydef initialize(name, price, quantity)@name = name@price = price@quantity = quantityenddef total_value@price * @quantityenddef to_s"#{@name} - 单价: #{@price}元, 库存: #{@quantity}"end
endclass Book < Productattr_accessor :author, :isbndef initialize(name, price, quantity, author, isbn)super(name, price, quantity)@author = author@isbn = isbnenddef to_ssuper + ", 作者: #{@author}, ISBN: #{@isbn}"end
endbook = Book.new("Ruby编程", 59.99, 10, "松本行弘", "978-7-121-12345-6")
puts book
puts "总价值: #{book.total_value}元"
模块
# 基本命名空间
module MyMathPI = 3.14159def self.circle_area(r)PI * r**2end
endputs MyMath::PI # => 3.14159
puts MyMath.circle_area(5) # => 78.53975# 嵌套命名空间
module Companymodule HRclass Employeeattr_accessor :nameendendmodule Financeclass Payrolldef calculate"计算工资"endendend
endemp = Company::HR::Employee.new
emp.name = "张三"
payroll = Company::Finance::Payroll.new
puts payroll.calculate# 作为Mixins基本混入
module Swimmabledef swim"我可以游泳"end
endclass Fishinclude Swimmable
endclass Doginclude Swimmable
endputs Fish.new.swim # => "我可以游泳"
puts Dog.new.swim # => "我可以游泳"# 作为Mixins多重混入
module Flyabledef fly"我可以飞"end
endmodule Runnabledef run"我可以跑"end
endclass Birdinclude Flyableinclude Runnable
endbird = Bird.new
puts bird.fly # => "我可以飞"
puts bird.run # => "我可以跑"# 使用extend添加类方法
module ClassMethodsdef class_method"这是一个类方法"end
endclass MyClassextend ClassMethods
endputs MyClass.class_method # => "这是一个类方法"# 同时包含实例方法和类方法
module MyModuledef instance_method"实例方法"endmodule ClassMethodsdef class_method"类方法"endenddef self.included(base)base.extend(ClassMethods)end
endclass MyClassinclude MyModule
endputs MyClass.new.instance_method # => "实例方法"
puts MyClass.class_method # => "类方法"# 模块前置和后置处理
module Loggabledef self.included(base)puts "#{base} 包含了 #{self}"enddef self.extended(base)puts "#{base} 扩展了 #{self}"end
endclass MyClassinclude Loggable # 输出: MyClass 包含了 Loggableextend Loggable # 输出: MyClass 扩展了 Loggable
end# 模块函数
module MathUtilsdef self.square(x)x * xendmodule_functiondef cube(x)x * x * xend
endputs MathUtils.square(3) # => 9
puts MathUtils.cube(3) # => 27
异常处理
beginresult = 10 / 0
rescue ZeroDivisionError => eputs "Error: #{e.message}" # => "Error: divided by 0"
ensureputs "Cleanup code here"
end