【KWDB 创作者计划】_ruby基础语法

发布于:2025-04-10 ⋅ 阅读:(36) ⋅ 点赞:(0)

以下是 Ruby 基础语法的简明总结,适合快速入门:


一、变量与常量

1. 局部变量

小写字母或下划线开头,作用域为当前代码块。

name = "Alice"
_age = 20

//局部变量附加:{{{{

声明与命名规则

  1. 命名格式

    • 以小写字母或下划线 _ 开头,如 name_count
    • 后续字符可包含字母、数字和下划线。
    • 避免与 Ruby 关键字(如 classdef)冲突。
  2. 声明方式

    • 通过赋值 = 隐式声明,无需显式类型。
    age = 25           # 声明局部变量 age
    _message = "Hello" # 声明局部变量 _message
    

作用域规则

  1. 代码块内外的可见性

    • 块参数会遮蔽外部变量

      x = 10
      3.times do |x|    # 块参数 x 遮蔽外部变量
        puts x          # 输出 0, 1, 2
      end
      puts x            # 输出 10(外部变量未被修改)
      
    • 无块参数时可访问外部变量

      x = 5
      3.times do
        x = 10         # 修改外部变量 x
      end
      puts x            # 输出 10
      
  2. 方法内的局部变量

    • 方法内部变量对外不可见:

      def test_method
        local_var = "内部变量"
      end
      test_method
      puts local_var    # NameError: undefined local variable
      
    • 方法无法访问定义它的外部局部变量:

      outer_var = "外部变量"
      def show_var
        puts outer_var  # NameError: undefined local variable
      end
      show_var
      
  3. 条件与循环中的变量

    • 即使条件未执行,变量也会被声明(初始化为 nil):

      if false
        a = 1          # 代码未执行,但变量 a 已声明
      end
      puts a            # 输出 nil
      
    • 循环(如 while)不创建新作用域:

      i = 0
      while i < 3
        inner = i
        i += 1
      end
      puts inner        # 输出 2
      

变量遮蔽与覆盖

  1. 内部作用域遮蔽外部变量

    x = 100
    1.times do
      x = 200          # 直接修改外部变量 x
      y = 300          # 声明新变量 y(作用域在块内)
    end
    puts x             # 输出 200
    puts y             # NameError: undefined local variable
    
  2. 方法参数与局部变量同名

    def demo(x)
      x = 20           # 修改的是参数 x,不影响外部变量
      puts x           # 输出 20
    end
    x = 10
    demo(x)
    puts x             # 输出 10
    

特殊场景

  1. 顶层作用域的局部变量

    • 在文件或交互式环境(如 irb)顶层定义的局部变量,作用域为当前文件或会话:
      top_var = "顶层变量"
      def show_top_var
        puts top_var   # NameError: undefined local variable
      end
      show_top_var
      
  2. 类/模块定义中的局部变量

    • 在类或模块定义中声明的局部变量,仅在该定义范围内有效:
      class MyClass
        class_var = "类定义内的局部变量"
        def self.show_var
          puts class_var # NameError: undefined local variable
        end
      end
      

最佳实践

  1. 避免变量遮蔽:谨慎使用与外部作用域同名的变量。
  2. 限制作用域:在最小必要范围内定义变量,减少副作用。
  3. 明确命名:使用有意义的变量名(如 user_count 而非 uc)。

总结

场景 行为
块内无参数赋值 可读写外部变量
块带同名参数 遮蔽外部变量,内部操作不影响外部
方法内部变量 仅在方法内有效,外部不可见
条件/循环中的变量 即使代码未执行,变量也会被声明(值为 nil
类定义中的变量 仅在类定义过程中有效,类方法无法访问

理解局部变量的作用域规则是编写可维护 Ruby 代码的基础,尤其在处理复杂逻辑时能避免意外的变量污染或覆盖。

//局部变量附加结束}}}}

2. 实例变量

@ 开头,属于对象实例。

@name = "Bob"

//实例变量附加:{{{{
实例变量(Instance Variables)是面向对象编程的核心概念,用于存储对象的状态。以下是其详细规则和使用方法:

定义与基本特性

  1. 命名规则

    • @ 符号开头,如 @name@age
    • 后续字符可包含字母、数字和下划线。
    • 默认值为 nil(未显式赋值时)。
  2. 作用域

    • 属于对象实例:每个对象的实例变量独立存在。
    • 在类的方法中可访问:在类的任何实例方法中均可读写。

声明与访问

  1. 直接赋值
class Person
  def initialize(name)
    @name = name  # 在 initialize 方法中初始化
  end

  def greet
    "Hello, #{@name}!"  # 在方法中访问
  end
end

person = Person.new("Alice")
puts person.greet  # => "Hello, Alice!"

//class Person代码的解释开始:
这段 Ruby 脚本定义了一个 Person 类,并演示了如何创建对象实例和调用方法。以下是逐行解释:

  1. 定义 Person
class Person
  # 类体开始
end
  • class Person:定义一个名为 Person 的类。
  • Ruby 的类名需以 大写字母开头,采用驼峰式命名。
  1. 构造方法 initialize
def initialize(name)
  @name = name  # 初始化实例变量 @name
end
  • initialize:类的构造方法,在调用 Person.new 时自动执行。
  • name:构造方法的参数,用于接收外部传入的值。
  • @name = name:将参数 name 赋值给实例变量 @name
    • @name:以 @ 开头的变量是实例变量,属于对象实例的私有状态。
  1. 实例方法 greet
def greet
  "Hello, #{@name}!"  # 使用实例变量 @name 拼接字符串
end
  • greet:定义一个名为 greet 的实例方法。
  • #{@name}:字符串插值语法,将 @name 的值嵌入字符串中。
  • 方法返回值为字符串(Ruby 中方法的最后一行的值会被自动返回)。
  1. 创建对象实例
person = Person.new("Alice")
  • Person.new("Alice"):调用 Person 类的 new 方法创建实例。
    • new 方法会触发 initialize 方法,并将 "Alice" 作为参数传递。
    • 此时 @name 被赋值为 "Alice"
  • person:变量指向新创建的 Person 实例对象。
  1. 调用方法并输出结果
puts person.greet  # => "Hello, Alice!"
  • person.greet:调用 person 实例的 greet 方法。
    • 方法返回字符串 "Hello, Alice!"
  • puts:输出字符串到控制台。

//class Person代码的解释结束

  1. 通过访问器方法
    Ruby 提供快捷方法生成 gettersetter
  • attr_reader:生成 getter 方法。
  • attr_writer:生成 setter 方法。
  • attr_accessor:生成 getter 和 setter。
class User
  attr_accessor :email  # 自动生成 @email 的读写方法
  attr_reader :id       # 只生成 @id 的读方法

  def initialize(id)
    @id = id
  end
end

user = User.new(1)
user.email = "alice@example.com"
puts user.email  # => "alice@example.com"

//访问器方法代码解释 开始
属性访问器(Attribute Accessors),属性访问器(Attribute Accessors)是一种元编程机制,用于快速生成实例变量的 getter(读方法)和 setter(写方法)。Ruby 提供了三个核心方法简化操作:
三种属性访问器

  1. attr_reader
    生成 只读方法(getter),允许外部读取实例变量。

    class User
      attr_reader :id  # 生成 def id; @id; end
    
      def initialize(id)
        @id = id
      end
    end
    
    user = User.new(1)
    puts user.id   # => 1
    user.id = 2    # NoMethodError(无写方法)
    
  2. attr_writer
    生成 只写方法(setter),允许外部修改实例变量。

    class User
      attr_writer :email  # 生成 def email=(value); @email = value; end
    
      def initialize(email)
        @email = email
      end
    end
    
    user = User.new("alice@example.com")
    user.email = "bob@example.com"  # 修改成功
    puts user.email                 # NoMethodError(无读方法)
    
  3. attr_accessor
    生成 读写方法(getter + setter),最常用。

    class Product
      attr_accessor :price  # 生成读方法和写方法
    
      def initialize(price)
        @price = price
      end
    end
    
    product = Product.new(100)
    product.price = 150
    puts product.price  # => 150
    

访问器的底层原理

  1. 手动实现等效代码

    class User
      # attr_reader :name 的等效代码
      def name
        @name
      end
    
      # attr_writer :name 的等效代码
      def name=(value)
        @name = value
      end
    end
    
  2. 动态生成方法
    attr_* 方法本质是通过元编程动态定义方法:

    class Class
      def my_attr_reader(name)
        define_method(name) do
          instance_variable_get("@#{name}")
        end
      end
    end
    

高级用法与技巧

  1. 批量定义访问器

    class Person
      attr_accessor :name, :age, :gender  # 多个属性
    end
    
  2. 添加自定义逻辑

    class Temperature
      attr_reader :celsius
    
      def celsius=(value)
        raise "温度不能低于绝对零度" if value < -273.15
        @celsius = value
      end
    end
    
    temp = Temperature.new
    temp.celsius = -300  # RuntimeError
    
  3. 结合初始化方法

    class Book
      attr_accessor :title, :author
    
      def initialize(title, author)
        @title = title
        @author = author
      end
    end
    
    book = Book.new("Ruby指南", "松本行弘")
    book.title = "Ruby高级编程"
    
  4. 继承行为
    父类的访问器方法会被子类继承:

    class Admin < User
    end
    admin = Admin.new(1)
    admin.email = "admin@example.com"  # 正常执行(继承 attr_accessor)
    

//访问器方法代码解释 结束

实例变量的特性

  1. 封装性
  • 实例变量默认是 私有 的,外部无法直接访问。
  • 必须通过方法暴露(如 attr_accessor)。
  1. 动态增删
    可在运行时动态添加或删除实例变量:
obj = Object.new
obj.instance_variable_set(:@x, 10)  # 动态添加 @x
puts obj.instance_variable_get(:@x) # => 10
obj.remove_instance_variable(:@x)   # 删除 @x

//动态增删附加 开始:
这段 Ruby 脚本演示了如何通过反射机制 动态管理实例变量
代码逐行解析

  1. 创建新对象
obj = Object.new
  • 作用:创建一个 Object 类的匿名实例。
  • 对象状态:此时 obj 没有任何预定义的实例变量。
  1. 动态添加实例变量 @x
obj.instance_variable_set(:@x, 10)
  • instance_variable_set 方法
    • 功能:直接为对象设置实例变量。
    • 参数
      • 第一个参数:符号形式的变量名(必须包含 @,如 :@x)。
      • 第二个参数:变量值(可以是任意对象)。
    • 结果:对象 obj 新增实例变量 @x,值为 10
  1. 读取实例变量 @x 的值
puts obj.instance_variable_get(:@x) # => 10
  • instance_variable_get 方法
    • 功能:直接读取对象的实例变量值。
    • 参数:符号形式的变量名(如 :@x)。
    • 返回值:变量的当前值,若变量不存在则返回 nil
  1. 删除实例变量 @x
obj.remove_instance_variable(:@x)
  • remove_instance_variable 方法
    • 功能:从对象中删除指定的实例变量。
    • 参数:符号形式的变量名(如 :@x)。
    • 返回值:被删除变量的值。
    • 注意:若变量不存在会抛出 NameError

关键方法和注意事项

方法名 用途 注意事项
instance_variable_set 动态设置实例变量 变量名必须@ 开头,否则抛出 NameError
instance_variable_get 动态读取实例变量 变量不存在时返回 nil,不会报错
remove_instance_variable 动态删除实例变量 变量不存在时抛出 NameError,需确保变量存在或使用 begin rescue 处理

使用场景

  1. 动态对象构造
    在运行时根据条件动态添加属性:

    data = { name: "Alice", age: 20 }
    obj = Object.new
    data.each { |key, value| obj.instance_variable_set("@#{key}", value) }
    
  2. 元编程和框架开发
    在编写灵活的程序结构时(如 ORM、序列化工具):

    class Serializer
      def serialize(obj)
        obj.instance_variables.each_with_object({}) do |var, hash|
          hash[var] = obj.instance_variable_get(var)
        end
      end
    end
    
  3. 调试和探索性编程
    快速查看或修改对象内部状态:

    user = User.find(1)
    user.instance_variable_set(:@password, "hacked") # 危险操作!仅用于演示
    obj = Object.new
    obj.instance_variable_set(:@不存在的方法, 100) # 合法但可能导致后续逻辑混乱
    
    # 使用下判断
    if obj.instance_variable_defined?(:@x)
      obj.remove_instance_variable(:@x)
    end
    

// 动态增删附加 结束

  1. 与类变量的对比
实例变量 (@var) 类变量 (@@var)
作用域 对象实例内 类及其所有实例共享
继承行为 子类对象不继承父类实例变量 子类共享父类的类变量

高级用法
5. 元编程访问

class Dog
  def initialize(name)
    @name = name
  end
end

dog = Dog.new("Buddy")

# 获取所有实例变量名
dog.instance_variables  # => [:@name]

# 检查是否存在实例变量
dog.instance_variable_defined?(:@name)  # => true
  1. 在模块中定义实例变量
module Loggable
  def log(message)
    @logs ||= []  # 若 @logs 不存在则初始化为空数组
    @logs << message
  end
end

class Service
  include Loggable
end

service = Service.new
service.log("Event 1")
service.instance_variable_get(:@logs)  # => ["Event 1"]

注意事项

  1. 避免未初始化访问
    实例变量未赋值时为 nil,需注意空值问题:

    class Product
      def print_price
        "Price: #{@price}"  # @price 未初始化时为 nil
      end
    end
    
    Product.new.print_price  # => "Price: "
    
  2. 命名冲突
    子类可能意外覆盖父类的实例变量:

    class Animal
      def initialize
        @name = "Animal"
      end
    end
    
    class Cat < Animal
      def initialize
        @name = "Cat"  # 覆盖父类的 @name
      end
    end
    

总结

场景 实例变量的行为
对象初始化 通过 initialize 方法赋值
方法间共享 同一对象的实例方法均可访问
动态管理 支持运行时增删
封装性 必须通过方法暴露给外部

实例变量是 Ruby 面向对象的核心机制,合理使用它们可以高效管理对象状态!

//实例变量附加结束}}}}

3. 类变量

@@ 开头,属于整个类。

@@count = 0

// 类变量 附加开始{{{{
在 Ruby 中,类变量(Class Variables)是一种特殊类型的变量,用于在类层级共享数据。

定义与基本特性

  1. 命名规则

    • @@ 开头,如 @@count@@config
    • 后续字符遵循变量命名规范(字母、数字、下划线)。
    • 必须显式初始化(否则抛出 NameError)。
  2. 作用域

    • 类层级共享:类变量属于类本身,被所有实例和子类共享。
    • 全局可见:在类定义、实例方法、类方法中均可访问。

基本用法示例

1. 类变量初始化与访问
class Counter
  @@count = 0  # 初始化类变量

  def self.increment
    @@count += 1
  end

  def self.total
    @@count
  end
end

Counter.increment
Counter.increment
puts Counter.total  # => 2
  1. 实例方法访问类变量
class User
  @@users = []

  def initialize(name)
    @name = name
    @@users << self  # 将实例自身加入类变量数组
  end

  def self.all_users
    @@users
  end
end

alice = User.new("Alice")
bob = User.new("Bob")
puts User.all_users.size  # => 2

类变量的继承行为

  1. 子类共享父类的类变量
class Parent
  @@value = 100

  def self.value
    @@value
  end
end

class Child < Parent
  def self.change_value
    @@value = 200
  end
end

Child.change_value
puts Parent.value  # => 200(父类的类变量被子类修改)
  1. 所有子类共享同一变量
class A
  @@list = []
end

class B < A; end
class C < A; end

B.class_variable_get(:@@list) << "item"
puts C.class_variable_get(:@@list)  # => ["item"]

类变量的替代方案:类实例变量
由于类变量的共享特性容易导致意外修改,Ruby 开发者常使用 类实例变量 作为替代:

  1. 类实例变量特性
  • @ 开头,属于类对象(而非类本身)。
  • 不被子类继承,每个类独立拥有自己的副本。
  • 通过类方法中的 attr_accessor 定义。
  1. 示例对比
class Parent
  @count = 0  # 类实例变量

  class << self
    attr_accessor :count  # 定义类实例变量的访问器
  end
end

class Child < Parent; end

Parent.count = 5
Child.count = 10
puts Parent.count  # => 5(不受子类影响)
puts Child.count   # => 10

类变量使用场景

场景 示例
全局类级计数器 统计实例数量、方法调用次数
共享配置 数据库连接、日志级别设置
缓存数据 存储类级别的计算结果或临时数据

注意事项与陷阱

  1. 初始化位置
    类变量必须在类或模块内部初始化(不能在其他作用域)。

    class Demo
      @@value = 0  # 正确:在类体内初始化
    end
    
    # @@value = 0  # 错误:顶层作用域无法初始化类变量
    
  2. 线程安全问题
    类变量在多线程环境中可能引发竞态条件,需加锁保护:

    class Counter
      @@mutex = Mutex.new
      @@count = 0
    
      def self.safe_increment
        @@mutex.synchronize { @@count += 1 }
      end
    end
    
  3. 避免过度共享
    类变量的全局性容易导致代码耦合,应谨慎使用。

总结对比

特性 类变量 (@@var) 类实例变量 (@var)
作用域 类及其所有子类共享 仅在定义它的类中有效
继承行为 子类修改影响父类和其他子类 不继承,每个类独立
初始化位置 必须在类或模块内部 可在类方法或类体内初始化
适用场景 需要跨继承树共享数据 需要类级别的私有状态

//类变量 附加结束}}}}

4. 全局变量

$ 开头,作用域全局。

$debug_mode = true

//全局变量附件开始
全局变量(Global Variables)是作用域覆盖整个程序(包括所有模块、类和方法的变量)。

全局变量的核心规则

  1. 命名规则

    • $ 开头,如 $counter$logger
    • 后续字符遵循变量命名规范(字母、数字、下划线)。
  2. 作用域

    • 全局可见:在程序的任何位置(包括类、模块、方法、块)均可读写。
  3. 默认值

    • 未初始化的全局变量值为 nil

基本用法示例

  1. 声明与赋值
$app_name = "MyApp"  # 定义全局变量

class User
  def print_app_name
    puts $app_name  # 在类内访问全局变量
  end
end

def log_message
  $app_name = "NewApp"  # 在方法内修改全局变量
end

log_message
User.new.print_app_name  # 输出 "NewApp"
  1. 预定义全局变量
    Ruby 有一些内置的全局变量(如 $!$@),用于访问系统信息或异常上下文:
begin
  1 / 0
rescue => e
  puts $!  # 输出最后抛出的异常信息(等同 e.message)
  puts $@  # 输出异常堆栈跟踪(等同 e.backtrace)
end

全局变量的优缺点
优点

  • 快速共享数据:无需通过参数传递,直接跨作用域访问。
  • 临时调试工具:快速记录程序状态。

缺点

  • 破坏封装性:导致代码耦合,难以追踪修改来源。
  • 命名冲突风险:全局变量名可能被意外覆盖。
  • 维护困难:大型项目中难以管理。

使用场景(谨慎选择!)

场景 示例
跨模块共享配置 日志级别、环境变量
临时调试或性能监控 记录方法调用次数
单例模式简单实现 全局唯一的数据库连接对象

替代方案(推荐优先使用)

  1. 常量(全大写命名)

    module Config
      APP_NAME = "MyApp"  # 常量,可被修改但会警告
    end
    
    puts Config::APP_NAME
    
  2. 类/模块变量

    class AppState
      @@instance_count = 0  # 类变量
    
      def self.increment
        @@instance_count += 1
      end
    end
    
  3. 单例模式

    require 'singleton'
    
    class Logger
      include Singleton
      attr_accessor :level
    
      def initialize
        @level = "INFO"
      end
    end
    
    Logger.instance.level = "DEBUG"
    

注意事项

  1. 避免滥用:仅在无其他替代方案时使用。

  2. 命名规范:使用明确的前缀(如 $myapp_logger),避免与内置全局变量冲突。

  3. 线程安全:多线程环境中需加锁保护。

    $counter = 0
    $counter_mutex = Mutex.new
    
    def increment_counter
      $counter_mutex.synchronize { $counter += 1 }
    end
    
  4. 重置全局变量:可通过赋值 nil 释放资源。

    $db_connection = nil  # 断开数据库连接并释放内存
    

内置全局变量

变量 用途
$! 最后抛出的异常对象
$@ 最后异常的堆栈跟踪信息
$? 最后执行的子进程状态
$0 当前执行的脚本文件名
$: Ruby 的加载路径(等同 $LOAD_PATH
$_ 最后读取的输入行(如 gets 结果)

最佳实践:除非必要,优先使用常量、类变量或依赖注入模式替代全局变量。
//全局变量附件结束

5. 常量

全大写字母,约定不可修改(修改会警告)。

PI = 3.14159

//常量附加开始
常量(Constants)是一种用于存储固定值的标识符,其命名以大写字母开头,通常用于定义配置、枚举值或全局共享数据。

常量的基本规则

  1. 命名规范

    • 必须以大写字母开头(如 PIMAX_SIZE)。
    • 约定全大写加下划线(如 DEFAULT_TIMEOUT),但也可用驼峰式(如 AppConfig)。
  2. 赋值与修改

    • 应保持不可变:Ruby 允许修改常量,但会发出警告。
    • 重新赋值触发警告:
      PI = 3.14
      PI = 3.14159  # 输出 warning: already initialized constant PI
      
  3. 作用域

    • 定义在类、模块或顶层作用域。
    • 通过命名空间访问(如 MyClass::CONST)。

常量的定义与访问

  1. 顶层常量(全局可见)
APP_NAME = "MyApp"  # 顶层常量

class User
  def show_app_name
    APP_NAME  # 直接访问
  end
end

puts APP_NAME  # => "MyApp"
  1. 类/模块内的常量
class MathUtils
  PI = 3.14159  # 类常量

  def circle_area(radius)
    PI * radius ** 2
  end
end

puts MathUtils::PI  # => 3.14159
  1. 模块中的常量
module Colors
  RED = "#FF0000"
end

class Car
  include Colors
end

puts Car::RED  # => "#FF0000"(通过 include 引入)

常量的查找规则

  1. 继承链查找
    子类会继承父类的常量,但可覆盖:
class Parent
  VALUE = 100
end

class Child < Parent
  VALUE = 200  # 覆盖父类常量
end

puts Parent::VALUE  # => 100
puts Child::VALUE    # => 200
  1. 作用域解析运算符 ::
module Outer
  CONST = "Outer"
  module Inner
    CONST = "Inner"
    def self.show
      puts CONST         # => "Inner"
      puts Outer::CONST  # => "Outer"
    end
  end
end

Outer::Inner.show

常量 vs 类变量

特性 常量 (CONST) 类变量 (@@var)
命名规则 大写字母开头 @@ 开头
可修改性 可修改(有警告) 可随意修改
作用域 类/模块或全局 类及其子类共享
继承行为 子类可覆盖 子类共享同一变量

最佳实践

  1. 避免修改常量
    如需可变配置,改用类方法或单例模式:

    class Config
      def self.timeout
        @timeout ||= 10  # 可修改且无警告
      end
    end
    
  2. 冻结常量(不可变对象)
    防止常量引用的对象被修改:

    COLORS = { red: "#FF0000" }.freeze
    COLORS[:red] = "#FF1234"  # RuntimeError: can't modify frozen Hash
    
  3. 使用模块组织常量

    module Settings
      TIMEOUT = 30
      API_KEY = "secret"
    end
    
    puts Settings::API_KEY
    

动态操作常量

  1. 动态定义与访问
class Dynamic
  const_set(:MAX, 100)         # 定义常量 MAX
  puts const_get(:MAX)         # => 100
  puts constants.include?(:MAX) # => true
end
  1. 检查常量存在性
if MyClass.const_defined?(:VERSION)
  puts MyClass::VERSION
end

常见错误

  1. 未初始化的常量

    puts UNDEFINED_CONST  # NameError: uninitialized constant UNDEFINED_CONST
    
  2. 命名空间遗漏

    module A
      module B
        CONST = 1
      end
    end
    puts B::CONST  # NameError: uninitialized constant B(需写 A::B::CONST)
    

//常量附加结束


二、数据类型

1. 数值(Numberic)

以下是 Ruby 中 数值类型(Numeric) 的详细解析,涵盖整数、浮点数、数值运算、类型转换以及实用技巧。

数值类型分类
Ruby 的数值类型分为 整数浮点数,所有数值均为对象,属于 Numeric 类的子类。

类型 类名 说明 示例
整数 Integer 包括小整数(Fixnum)和大整数(Bignum),Ruby 自动处理类型转换 42, 12345678901234567890
浮点数 Float 双精度浮点数,遵循 IEEE 754 标准 3.14, 6.022e23
有理数 Rational 精确分数(需手动创建或引入库) Rational(3, 4) => 3/4
复数 Complex 复数类型(需手动创建或引入库) Complex(2, 3) => 2+3i

整数(Integer)

  1. 表示方式
  • 十进制:默认写法,如 123
  • 二进制:以 0b0B 开头,如 0b1010(十进制的 10)。
  • 八进制:以 00o 开头,如 0o755(十进制的 493)。
  • 十六进制:以 0x 开头,如 0xFF(十进制的 255)。
  1. 自动大整数支持
    Ruby 自动处理整数溢出,小整数(Fixnum)和大整数(Bignum)无缝切换:
a = 123           # => 123(Fixnum)
b = 1234567890 * 9876543210  # => 12193263113702179500(Bignum)
  1. 常用方法
方法 说明 示例
times { |i| } 循环指定次数 3.times { |i| puts i } 输出 0,1,2
even?, odd? 判断奇偶 4.even? => true
to_s(base) 转换为字符串(指定进制) 255.to_s(16) => "ff"
abs 绝对值 -5.abs => 5

浮点数(Float)
5. 表示方式

  • 常规写法:3.14, -0.001
  • 科学计数法:6.022e23(6.022 × 10²³)。
  1. 精度问题与解决方案
    浮点数计算可能因精度丢失导致误差:
0.1 + 0.2  # => 0.30000000000000004(并非精确的 0.3)

解决方案

  • 使用 Rational 类型
    (Rational(1, 10) + Rational(2, 10)).to_f  # => 0.3
    
  • BigDecimal(高精度计算):
    require 'bigdecimal'
    a = BigDecimal("0.1")
    b = BigDecimal("0.2")
    a + b  # => 0.3e0
    

数值运算

  1. 基本运算符
运算符 说明 示例
+ 加法 5 + 3 => 8
- 减法 5 - 3 => 2
* 乘法 5 * 3 => 15
/ 除法 5 / 2 => 2(整数除法)
5.to_f / 2 => 2.5
% 取模 5 % 2 => 1
** 幂运算 2 ** 3 => 8
  1. 除法行为
  • 整数除法:结果自动向下取整。
    7 / 3    # => 2
    
  • 浮点除法:强制转换为浮点数。
    7.to_f / 3  # => 2.333...
    7 / 3.0     # => 2.333...
    
  1. 链式比较
    Ruby 支持数学中的链式比较:
1 < 2 < 3     # => true
5 <= x <= 10  # 判断 x 是否在 5 到 10 之间

类型转换

目标类型 方法 示例
整数转浮点 to_f 5.to_f => 5.0
浮点转整数 to_i(截断) 3.9.to_i => 3
四舍五入 round 3.6.round => 4
向上取整 ceil 3.2.ceil => 4
向下取整 floor 3.9.floor => 3
字符串转数值 to_i, to_f "42".to_i => 42

实用技巧

  1. 随机数生成
rand(10)        # 生成 0~9 的随机整数
rand(5.0..10.0) # 生成 5.0 到 10.0 的随机浮点数
  1. 数值格式化
sprintf("%.2f", 3.1415)  # => "3.14"
3.1415.round(2)          # => 3.14(四舍五入保留两位小数)
  1. 数值范围检查
(1..100).cover?(50)  # => true(检查数值是否在范围内)
  1. 字符串(String)
    单引号(不转义)或双引号(支持转义和插值)。

    str1 = 'Hello \n World'  # 输出换行符
    str2 = "Hello #{name}"   # 插值:Hello Alice
    
  2. 符号(Symbol)
    轻量级字符串,以 : 开头,常用于哈希键。

    :user_id
    
  3. 数组(Array)
    有序集合,通过索引访问。

    nums = [1, 2, 3]
    nums[0]  # => 1
    
  4. 哈希(Hash)
    键值对集合,键可以是任意对象。

    person = { name: "Alice", age: 20 }
    person[:name]  # => "Alice"
    
  5. 范围(Range)
    表示连续区间,常用于迭代。

    (1..5).each { |n| puts n }  # 1到5
    (1...5).each { |n| puts n } # 1到4
    

三、运算符

  1. 算术运算符
    +, -, *, /, %, **(幂运算)。

    2 ** 3  # => 8
    10 % 3  # => 1
    
  2. 比较运算符
    ==, !=, >, <, >=, <=, <=>(返回 -1, 0, 1)。

    5 <=> 3  # => 1(5 > 3)
    
  3. 逻辑运算符
    &&, ||, !(也可用 and, or, not,但优先级不同)。

    true && false  # => false
    
  4. 赋值运算符
    =, +=, -=, *=, /=, %=

    x = 5
    x += 3  # => 8
    

四、控制结构

  1. 条件判断

    # if/elsif/else
    if age >= 18
      puts "Adult"
    elsif age > 0
      puts "Child"
    else
      puts "Invalid"
    end
    
    # 三元运算符
    result = (score > 60) ? "Pass" : "Fail"
    
  2. 循环

    # while 循环
    i = 0
    while i < 3
      puts i
      i += 1
    end
    
    # until 循环
    until i >= 3
      puts i
      i += 1
    end
    
    # for 循环(较少使用)
    for num in [1, 2, 3]
      puts num
    end
    
  3. 迭代器

    # each 方法
    (1..3).each { |n| puts n }
    
    # map 方法
    doubled = [1, 2, 3].map { |n| n * 2 }  # => [2, 4, 6]
    

五、方法定义

  1. 基本语法

    def greet(name)
      "Hello, #{name}!"
    end
    greet("Ruby")  # => "Hello, Ruby!"
    
  2. 默认参数

    def add(a, b = 1)
      a + b
    end
    add(3)    # => 4
    add(3, 5) # => 8
    
  3. 可变参数

    def sum(*nums)
      nums.sum
    end
    sum(1, 2, 3)  # => 6
    

六、异常处理

begin
  # 可能出错的代码
  result = 10 / 0
rescue ZeroDivisionError => e
  puts "Error: #{e.message}"
ensure
  puts "Cleanup code here"
end

七、注释

  1. 单行注释

    # 这是一个注释
    
  2. 多行注释

    =begin
    这是一个多行注释
    可以写多行内容
    =end
    

八、特殊语法

  1. % 符号快捷语法

    %w[apple banana cherry]  # => ["apple", "banana", "cherry"](字符串数组)
    %i[red green blue]       # => [:red, :green, :blue](符号数组)
    
  2. 并行赋值

    a, b = 1, 2  # a=1, b=2
    a, b = b, a   # 交换值:a=2, b=1
    

九、代码块(Block)

  1. 使用 {}do...end

    # 单行用 {}
    [1, 2, 3].each { |n| puts n }
    
    # 多行用 do...end
    [1, 2, 3].each do |n|
      puts "Number: #{n}"
    end
    
  2. 自定义接受块的方法

    def repeat(times)
      times.times { yield }  # yield 调用块
    end
    
    repeat(3) { puts "Hello!" }  # 输出 3 次 Hello
    

十、常用方法示例

  1. 字符串操作

    "ruby".upcase      # => "RUBY"
    "HELLO".downcase   # => "hello"
    "  test  ".strip   # => "test"
    
  2. 数组操作

    [1, 2, 3].include?(2)  # => true
    [1, 2, 3].push(4)      # => [1, 2, 3, 4]
    [1, 2, 3].join("-")    # => "1-2-3"
    

十一、ruby保留关键词

以下是 Ruby 的 全部关键字列表(基于 Ruby 3.x 版本),这些单词具有特殊语法含义,不可用作变量名或方法名:

控制流

关键字 说明
if 条件判断
else 条件分支
elsif 多条件分支
unless 反向条件判断
case 多条件匹配
when case 语句的分支条件
then 简化条件语法
end 结束代码块

循环与迭代

关键字 说明
while 条件循环
until 反向条件循环
for 遍历循环(较少使用)
in 用于 forcase
do 定义循环/块的开始
break 跳出循环
next 跳过当前迭代
redo 重新执行当前迭代
retry 重新开始循环(已废弃)

类与模块

关键字 说明
class 定义类
module 定义模块
def 定义方法
undef 取消方法定义
alias 方法别名
super 调用父类方法
self 当前对象

异常处理

关键字 说明
begin 异常处理块开始
rescue 捕获异常
ensure 确保执行(类似 finally)
raise 抛出异常
throw 抛出符号(与 catch 配合)
catch 捕获符号

访问控制

关键字 说明
public 公开方法
private 私有方法
protected 受保护方法

逻辑与运算符

关键字 说明
and 逻辑与(低优先级)
or 逻辑或(低优先级)
not 逻辑非
true 布尔真值
false 布尔假值
nil 空值

其他核心关键字

关键字 说明
return 从方法返回值
yield 调用块
__FILE__ 当前文件名(伪变量)
__LINE__ 当前行号(伪变量)
BEGIN 程序启动前执行的代码块
END 程序退出前执行的代码块
defined? 检查标识符是否已定义

模式匹配(Ruby 2.7+)

关键字 说明
in 模式匹配分支

注意

  1. 非关键字但需谨慎使用
    putsgets 等是全局方法,而非关键字。
    proclambda 是类或方法,可被覆盖(但强烈建议不要这样做)。

  2. 版本差异
    retry 在循环中已废弃(但仍可用于 begin/rescue 块)。
    in 在 Ruby 2.7+ 中用于模式匹配。


完整列表(按字母排序):
__FILE__, __LINE__, BEGIN, END, alias, and, begin, break, case, catch, class, def, defined?, do, else, elsif, end, ensure, false, for, if, in, module, next, nil, not, or, redo, rescue, retry, return, self, super, then, true, undef, unless, until, when, while, yield


总结

Ruby 语法以简洁灵活著称,核心特点是:

  • 无分号,代码块通过缩进或 end 结束。
  • 动态类型,无需声明变量类型。
  • 一切皆对象,方法调用可链式操作。

建议通过实际编码练习巩固语法,例如尝试编写小型脚本或使用 Ruby Playground 在线工具。

— END —