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

以下是 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 代码的基础,尤其在处理复杂逻辑时能避免意外的变量污染或覆盖。

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

  1. 实例变量
    @ 开头,属于对象实例。
    @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 = "[email protected]"
puts user.email  # => "[email protected]"

//访问器方法代码解释 开始
属性访问器(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("[email protected]")
    user.email = "[email protected]"  # 修改成功
    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 = "[email protected]"  # 正常执行(继承 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) |
    |----------------|---------------------------|---------------------------|
    | 作用域 | 对象实例内 | 类及其所有实例共享 |
    | 继承行为 | 子类对象不继承父类实例变量 | 子类共享父类的类变量 |

高级用法

  1. 元编程访问
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 面向对象的核心机制,合理使用它们可以高效管理对象状态!

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

  1. 类变量
    @@ 开头,属于整个类。
    @@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)
作用域 类及其所有子类共享 仅在定义它的类中有效
继承行为 子类修改影响父类和其他子类 不继承,每个类独立
初始化位置 必须在类或模块内部 可在类方法或类体内初始化
适用场景 需要跨继承树共享数据 需要类级别的私有状态

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

  1. 全局变量
    $ 开头,作用域全局。

    $debug_mode = true
    
  2. 常量
    全大写字母,约定不可修改(修改会警告)。

    PI = 3.14159
    

二、数据类型

  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 —

你可能感兴趣的:(Ruby,开发语言,ruby,ruby3.1.2,后端)