【问题标题】:How to define a class method :[] when using class_eval如何定义类方法:[] 使用 class_eval 时
【发布时间】:2021-09-12 23:03:11
【问题描述】:

我正在使用quaternion gem 并想为 :[] 运算符定义一个类方法,该方法从数组中创建一个新的四元数。我试过了

Quaternion.class_eval do
  def self.[ary]
    Quaternion.new(*ary)
  end
end

但这会产生语法错误。我该怎么做?

【问题讨论】:

  • Methods 的文档包含定义运算符方法的示例,包括 [][]=

标签: ruby quaternions


【解决方案1】:

方法的名称[],但它仍然以通常的方式获取它的参数列表

def self.[](ary)
  ...
end

那你叫它Quaternion[ary]

【讨论】:

    【解决方案2】:

    长话短说,能够使用Quaternion[arg],你想像下面这样定义它

      def self.[](arg)
        Quaternion.new(*ary)
      end
    

    有趣的是,为什么它会起作用? 嗯,它是 ruby​​ 的语法糖

    foo[bar]foo.[](bar)是一样的

    foo[bar]=bazfoo.[]=(bar, baz) 相同

    a + b实际上是a.+(b)

    如果你想定义它,它看起来像这样:

    def [](key)
      ...
    end
    
    def []=(key, value)
      ...
    end
    
    def +(arg)
      ...
    end
    

    这是因为 ruby​​ 中的方法名可以有特殊字符。

    如果您对它的内部标记化和解析方式感兴趣,可以阅读显微镜下的 Ruby,这是对该主题的一个很好的介绍。我还找到了这本免费的书,它也涉及到这个主题->https://ruby-hacking-guide.github.io/(查看第 8 章方法调用部分)

    【讨论】:

    • "而且 foo[bar]=baz 和 foo.[](bar, baz)" 在这里漏掉了一个等号。应该阅读 “而且 foo[bar]=baz 与 foo.[]=(bar, baz) 相同” 并让 OP 意识到他们的对象必须将方法定义为 @987654331 @
    • 你是对的。我错过了那个等号。感谢您指出这一点:)
    猜你喜欢
    • 2012-03-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多