Ruby 语言学习笔记:基础、面向对象与元编程
9 minute read

Ruby,一种优雅而富有表现力的动态脚本语言,以其简洁的语法和强大的面向对象特性吸引了众多开发者。本文将记录我在学习Ruby过程中的一些关键笔记,涵盖其基础语法、深刻的面向对象模型以及引人入胜的元编程能力,旨在为初学者提供一个清晰的学习脉络,并为有经验的开发者提供一些回顾与启发。

一、 Ruby 基础语法

Ruby的语法设计非常注重可读性和简洁性。

  • 变量与数据类型

    • 局部变量:以小写字母开头(如 name)。
    • 实例变量:以 @ 开头(如 @age)。
    • 类变量:以 @@ 开头(如 @@count)。
    • 全局变量:以 $ 开头(如 $global_var)。
    • 常量:以大写字母开头(如 PI)。
    • Ruby支持基本数据类型,如整型(Integer)、浮点型(Float)、字符串(String)、布尔值(TrueClass/FalseClass)、NilClass(nil对象)。
  • 控制流

    • if/elsif/else/end:条件判断。
    • unless:与if相反。
    • while/enduntil/end:循环。
    • for/in/do/end:另一种循环形式。
    • loop/do/end:无限循环。
    • breaknext:用于中断或跳过循环的当前迭代。
  • 方法(Methods)

    • 定义方法使用 def 关键字,以 end 结束。
    • 方法调用时,括号是可选的(如 puts "Hello")。
    • 方法可以有参数,也可以没有。
    • Ruby方法默认返回最后一个表达式的值。
  • 集合(Collections)

    • 数组(Array):有序的元素集合,使用 [] 定义,如 [1, 2, 3]
    • 哈希(Hash):键值对的集合,使用 {} 定义,如 {'name' => 'Alice', 'age' => 30}。Ruby 1.9+ 支持新的哈希语法 { key: value }
  • 块(Blocks):Ruby的一大特色,是匿名代码片段,可以传递给方法。块使用 {}do...end 定义。

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

二、 Ruby 的面向对象模型

Ruby被广泛认为是“纯粹的面向对象语言”,因为它几乎一切皆对象,包括基本类型和方法本身。

  • 类(Class)与对象(Object)

    • 使用 class 关键字定义类,如 class Dog ... end
    • new 是类的方法,用于创建对象实例。
    • 每个对象都有一个 class 方法,可以返回其所属的类。
  • 继承(Inheritance)

    • Ruby支持单重继承,使用 < 符号表示继承关系。
    • Object 类是所有类的根基类。
  • 封装(Encapsulation)

    • 实例变量默认是私有的,只能通过公共方法(Getter/Setter)访问。
    • attr_reader, attr_writer, attr_accessor 是Ruby提供的方便的宏,用于自动生成getter、setter或两者。
  • 多态(Polymorphism)

    • 鸭子类型(Duck Typing):如果一个对象“像鸭子一样叫,像鸭子一样走路”,那么它就是一只鸭子。Ruby不关心对象的具体类型,只关心它是否能响应某个方法。
  • 模块(Modules)

    • 模块用于组织代码和实现Mixin(混入)。
    • 通过 include 关键字将模块的方法混入类中,实现代码的复用。
    • 通过 extend 关键字将模块的方法作为类方法混入类中。
  • Mixins:Ruby通过Mixins(通常使用模块实现)来模拟多重继承,允许一个类拥有来自多个模块的功能。

三、 Ruby 的元编程(Metaprogramming)

元编程是指编写能够生成或操作其他程序的程序。Ruby强大的元编程能力是其魅力和灵活性的重要来源。

  • 动态方法定义

    • define_method:可以在运行时动态地定义方法。
    1class MyClass
    2  def self.create_method(method_name, &block)
    3    define_method(method_name, &block)
    4  end
    5end
    6
    7MyClass.create_method(:say_hello) { puts "Hello from dynamic method!" }
    8obj = MyClass.new
    9obj.say_hello # => Hello from dynamic method!
    
  • 动态方法调用

    • send:动态调用对象的方法。
    • public_send:类似于send,但会检查方法的可见性。
    1obj.send(:say_hello) # => Hello from dynamic method!
    
  • 方法丢失(Method Missing)

    • method_missing:当对象尝试调用一个不存在的方法时,method_missing会被调用。这使得我们可以实现非常灵活的代理、DSL(领域特定语言)等。
     1class DynamicAttribute
     2  def method_missing(method_name, *args, &block)
     3    if method_name.to_s.start_with?("get_")
     4      attribute_name = method_name.to_s.sub("get_", "")
     5      puts "Fetching attribute: #{attribute_name}"
     6      # 实际应用中会从某个地方获取值
     7      return "Value for #{attribute_name}"
     8    else
     9      super # 如果不是我们处理的,则调用父类的方法,最终可能抛出NoMethodError
    10    end
    11  end
    12end
    13
    14da = DynamicAttribute.new
    15puts da.get_user_id # => Fetching attribute: user_id \n Value for user_id
    
  • 代码块的执行与获取

    • instance_evalclass_eval:允许在一个对象的上下文(instance_eval)或类的上下文(class_eval)中执行一段Ruby代码。这常用于DSL的实现。
     1class Person
     2  attr_accessor :name, :age
     3
     4  def setup(&block)
     5    instance_eval(&block)
     6  end
     7end
     8
     9p = Person.new
    10p.setup do
    11  self.name = "Bob"
    12  self.age = 25
    13end
    14puts p.name # => Bob
    15puts p.age  # => 25
    

四、 Ruby on Rails 的联系

Ruby on Rails(Rails)是一个非常流行的Web开发框架,它大量地运用了Ruby的面向对象和元编程特性。例如:

  • ActiveRecord:它通过元编程动态地为数据库表生成模型类和对应的操作方法,使得数据库交互变得非常简洁。
  • DSL:Rails的许多配置和路由定义都使用了Ruby的DSL,这得益于Ruby的块和方法调用语法。

结语

Ruby语言的魅力在于其对开发者的友好程度和其内在的强大灵活性。从基础的语法到深刻的面向对象设计,再到令人惊叹的元编程能力,Ruby为开发者提供了一个创造性无限的平台。掌握Ruby,不仅能写出优雅的代码,更能让你理解和驾驭像Ruby on Rails这样的强大框架,从而在Web开发领域取得更大的成就。