【问题标题】:Ruby: I need help understanding the following code involving method_missing(method, *args, &block)Ruby:我需要帮助理解以下涉及 method_missing(method, *args, &block) 的代码
【发布时间】:2025-11-24 04:50:02
【问题描述】:

我在尝试了解如何创建自己的 method_missing 方法时遇到了这段代码,但我不明白。 我不明白的是这些部分:method_sym[-1] == "=" 和 method_sym[0..-2] 他们指的是什么?我在 irb 中尝试了一些模拟,但这只是返回了一些奇怪的东西。

谁能帮我分析一下?我真的很感激。谢谢!

class UberHash
  def method_missing(method_sym, *args, &block)
    if method_sym[-1] == "="
      instance_variable_set("@#{method_sym[0..-2]}", args[0])
    else
      instance_variable_get("@#{method_sym}")
    end
  end
end

【问题讨论】:

  • 这是重塑openstuct的一种方式。
  • 刚刚在 OpenStruct 上达到顶峰,看起来很有趣,谢谢!

标签: ruby class methods instance-variables method-missing


【解决方案1】:

method_sym,即method_missing的第一个参数是代表方法名称的Symbol实例。因此,例如,如果您调用

a.foo

而 Ruby 找不到 foo 方法,将调用 a.method_missing(:foo)

接下来,Symbol#[] 方法用于返回符号的第 n 个字符或某些字符范围,如果您将 Range 传递给它。传入此方法的-1 表示“最后一个字符”。 -2 表示“最后一个字符之前的字符”等。所以:

symbol = :foo
symbol[-1]
# => "o"
symbol[0..-2]
# => "fo"

args 表示传递给缺失方法的所有参数。所以,如果你调用你的方法:

a.foo(arg1, arg2, arg3)

missing_method 中的args 将是:

[arg1, arg2, arg3]

Ruby 中的方法可以以= 结尾,这就是你创建setter 方法的方式,例如:

class A
  def foo=(value)
    @foo = value
  end
end

这是常规方法,A.new.foo = some_value 只是一个语法糖,在底层,它相当于A.new.foo=(some_value)。所以如果你打电话

b.foo = 'value'

b.foo= 未定义,Ruby 将调用:

b.method_missing(:foo=, 'value')

因此=method_sym[-1]

【讨论】:

  • 谢谢你,这很有帮助。我没有得到method_missing(这里是method_sym)的第一个参数是缺失方法的第一个参数。在这种情况下,*args 是剩余参数,还是所有参数(包括第一个参数)?
  • 另外,我仍然不确定这一切的作用。例如,为什么 method_sym[-1] 会等于 "=" ?
  • @OlivierGirardot 我回答了你的两个问题。
  • 当您使用 splat (*) 时,它会收集剩余的参数。 ** 做同样的事情,但用于关键字参数。
  • 非常感谢!这一切对我来说都很新鲜,所以我需要仔细研究。比以前清晰多了,非常感谢您的帮助:)
最近更新 更多