MST

星途 面试题库

面试题:Ruby 动态派发的复杂场景处理

假设你有一个 Ruby 类,其中包含一些常规方法。现在需要实现一种机制,当调用以特定前缀(如 `custom_`)开头的不存在的实例方法时,能够根据方法名的剩余部分进行不同的数据库查询操作(可以假设已有数据库连接相关的方法),请编写代码实现这种动态派发机制,并阐述其中涉及到的 `method_missing` 和 `define_method` 等相关概念的运用。
44.0万 热度难度
编程语言Ruby

知识考点

AI 面试

面试题答案

一键面试
class DynamicMethodHandler
  def method_missing(method_name, *args, &block)
    method_name = method_name.to_s
    if method_name.start_with?('custom_')
      query_part = method_name[7..-1]
      result = perform_database_query(query_part)
      return result
    end
    super
  end

  def respond_to_missing?(method_name, include_private = false)
    method_name.to_s.start_with?('custom_') || super
  end

  private

  def perform_database_query(query_part)
    # 这里假设已经有数据库连接相关方法,实现具体查询逻辑
    "Query result for #{query_part}"
  end
end

# 测试
handler = DynamicMethodHandler.new
puts handler.custom_some_query # 输出: Query result for some_query

method_missing 概念运用

method_missing 是 Ruby 中的一个方法,当对象接收到无法识别的方法调用时会调用它。在上述代码中,我们重写了 method_missing 方法,当接收到以 custom_ 开头的方法调用时,会从方法名中提取出查询部分,并执行数据库查询操作。如果方法名不是以 custom_ 开头,则调用 super 让 Ruby 按照常规方式处理未识别的方法调用。

define_method 概念运用(这里没有直接使用,但在其他场景下可关联理解)

define_method 是 Ruby 元编程中的一个强大工具,它允许在运行时动态地为对象或类定义新的方法。例如,如果在处理动态方法调用时,发现某个以 custom_ 开头的方法经常被调用,为了提高效率,可以使用 define_method 在首次调用时为类动态定义该方法,这样后续调用就不需要经过 method_missing 逻辑,直接执行已定义好的方法体。示例如下:

class DynamicMethodHandler
  def method_missing(method_name, *args, &block)
    method_name = method_name.to_s
    if method_name.start_with?('custom_')
      query_part = method_name[7..-1]
      define_method(method_name) do
        perform_database_query(query_part)
      end
      send(method_name, *args, &block)
    else
      super
    end
  end

  def respond_to_missing?(method_name, include_private = false)
    method_name.to_s.start_with?('custom_') || super
  end

  private

  def perform_database_query(query_part)
    # 这里假设已经有数据库连接相关方法,实现具体查询逻辑
    "Query result for #{query_part}"
  end
end

在这个改进版本中,首次调用以 custom_ 开头的方法时,通过 define_method 动态定义该方法,后续调用就直接执行定义好的方法,提高了效率。