定义自定义Ruby运算符

Dim*_*ets 5 ruby metaprogramming operators

问题是:我可以在Ruby中定义自己的自定义运算符,除了" 运算符表达式 "中的自定义运算吗?

例如: 1 %! 2

Dar*_*tle 6

是的,虽然有一些警告,但可以创建自定义运算符.Ruby本身并不直接支持它,但是superators gem在将操作符链接在一起时做了一个聪明的技巧.这允许您创建自己的运算符,但有一些限制:

$ gem install superators19
Run Code Online (Sandbox Code Playgroud)

然后:

require 'superators19'

class Array
  superator "%~" do |operand|
    "#{self} percent-tilde #{operand}"
  end
end

puts [1] %~ [2]
# Outputs: [1] percent-tilde [2]
Run Code Online (Sandbox Code Playgroud)

由于上述限制,我不能做你的1 %! 2榜样.该文档已全部细节,但Fixnums不能给予superator,而!不能在一个superator.


die*_*mes 5

不可以。你只能定义 ruby​​ 中已经指定的运算符,+、-、!、/、% 等(你看到了列表)

你可以亲眼看看这是行不通的

def HI
  def %!
    puts "wow"
  end
end
Run Code Online (Sandbox Code Playgroud)

这主要是因为必须扩展语法解析器才能接受使用新运算符的任何代码。


正如达山提到的,仅这个例子可能不足以认识到根本问题。相反,让我们仔细看看解析器如何使用此运算符处理一些示例代码。

3 %! 0
Run Code Online (Sandbox Code Playgroud)

虽然在我的间距下,很明显这应该是3.%!(0)没有间距的,但它变得更难看到。

3%!也可以看作3.%(0.!)解析器不知道该选择哪个。目前,还没有简单的方法可以告诉它。相反,我们可能希望覆盖 的含义,3.%(0.!)但这并不完全定义一个新的运算符,因为我们仍然仅限于 ruby​​ 的可解析符号

  • 不符合逻辑?当解析器遇到任何运算符时,它实际上是方法调用的语法糖。因此方法调度规则像平常一样应用。定义内置运算符只是定义您自己的方法来利用这种糖。定义新运算符需要解析器知道如何解析新运算符。例如,它对 `var%!` 做了什么。这是 `var.send(:%).send(:!)` 还是 `var.send(:%!)`。这有道理吗? (3认同)