【问题标题】:Defining a new logical operator in Ruby在 Ruby 中定义一个新的逻辑运算符
【发布时间】:2011-11-28 14:53:37
【问题描述】:

这是一个非常无聊的白日梦,但是否有可能通过一些巧妙的元编程技巧在 Ruby 中定义一个新的逻辑运算符?我想定义一个but 运算符。

例如,如果我想在x 但不是y 为真时做某事,我必须写如下内容:

if x and not y

但我想写

if x but not y

它的工作方式应该与and 完全相同,但需要程序员合理使用以增加代码的易读性。

【问题讨论】:

  • 不改变解析器。构造的语义不清楚,IMO,没有and。
  • 你能举例说明为什么你认为语义不清楚吗?它的工作原理与and 完全相同。唯一的区别是它暗示 x 的逻辑值是 != y 的逻辑值。
  • if x but y 是什么意思?这不是技术问题,而是“戴夫认为不清楚”的问题——纯粹是优先考虑。
  • 这将是一个糟糕的程序员滥用该结构的例子。 unless x but y 可能会稍微好一点——尽管它仍然有点垃圾。它基本上很适合我在问题中描述的用例,但仅此而已 - 这就是为什么它是一个空闲的白日梦!
  • 我的意思是,滥用现有结构同样容易:例如unless not x and not !y。

标签: ruby metaprogramming


【解决方案1】:

如果不编辑 Ruby 解析器和源代码并编译新版本的 Ruby,您就做不到。如果你愿意,你可以使用这个丑陋的语法:

class Object
  def but(other)
    self and other
  end
end

x.but (not y)

请注意,您不能删除此 sn-p 中的括号或空格。它还会将代码的功能隐藏给阅读您代码的其他人。不要这样做。

【讨论】:

  • 更重要的是,这个“解决方案”将始终评估 both x 和 y(无短路),并且会以 相反的顺序(y 然后x)。
  • @MladenJablanović:您只需定义一组运算符(我们称它们为 惰性运算符),它们将被转换为 a.OP { b } 而不是 a.OP(b),然后它会完全可以覆盖它们。几年前,我在消息发送时重新实现了所有 Ruby 的布尔运算符,我什至使用了RubySpec 测试套件来验证它们的正确行为:GitHub.Com/JoergWMittag/B001e BTW:请关注实际 该代码的语义...这是我编写的第一个 Ruby 项目,代码糟糕 :-)
  • 我同意。这个答案中最好的部分是不要这样做。 +1
【解决方案2】:

如果您真的想这样做,请尝试编辑 parse.y 并重新编译 Ruby。这就是定义 Ruby 语法的地方。

【讨论】:

  • 为什么我会说它不推荐用于任何具有实际应用的东西,我认为用户可以从尝试中学到一些东西。
【解决方案3】:

正如其他人已经指出的那样,您不能在 Ruby 中定义自己的运算符。运算符集是预定义和固定的。您所能做的就是通过响应适当的消息来影响一些现有运算符(即被翻译成消息发送的运算符)的语义。

当然,你可以很容易地实现but方法:

class Object
  def but
    self && yield
  end
end

Object.new.but { not true }

【讨论】:

    猜你喜欢
    • 2011-03-14
    • 1970-01-01
    • 1970-01-01
    • 2015-11-24
    • 1970-01-01
    • 1970-01-01
    • 2020-12-20
    相关资源
    最近更新 更多