Ruby一元代波形(`~`)方法

Chr*_*ele 11 ruby syntax operators literals

我在一个pry REPL中闲逛,发现了一些非常有趣的行为:代字号方法.

看来Ruby语法有一个内置的文字一元运算符~,只是坐在那里.

这意味着~Object.new将消息发送~到以下实例Object:

class Object
  def ~
    puts 'what are you doing, ruby?'
  end
end
~Object.new #=> what are you doing, ruby?
Run Code Online (Sandbox Code Playgroud)

这看起来很酷,但很神秘.Matz基本上是想给我们自己定制的一元运算符吗?

我在rubydocs中可以找到的唯一参考是在运算符优先级注释中,它被排在第一位最高优先级运算符旁边!,unary +这对于一元运算符是有意义的.(关于接下来两个优先级的有趣勘误,**那么unary -,看看这个问题.)除此之外,没有提到这个实用程序.

我可以通过在~=,!, and~~>`问题中搜索找到对这个运算符的两个值得注意的引用是这个这个.他们都注意到它的实用性,古怪性和默默无闻,而没有进入它的历史.

在我即将注销~作为为对象提供自定义一元操作符行为的一种很酷的方式之后,我找到了一个实际用于ruby的地方 - fixnum(整数).

~2回报-3.~-1回报1.所以它否定了一个整数并减去一个......出于某种原因?

任何人都可以启发我作为波形符操作符在红宝石中的独特和意外行为的目的吗?

Chr*_*ele 5

使用 pry 检查该方法:

show-method 1.~

From: numeric.c (C Method):
Owner: Fixnum
Visibility: public
Number of lines: 5

static VALUE
fix_rev(VALUE num)
{
    return ~num | FIXNUM_FLAG;
}
Run Code Online (Sandbox Code Playgroud)

虽然这对我来说是难以理解的,但它促使我寻找 C 一元运算~符。存在一种:它是按位 NOT 运算符,它翻转二进制整数 ( ~1010=> 0101) 的位。由于某种原因,这会比 Ruby 中的十进制整数的负数小 1。

更重要的是,由于 ruby​​ 是一种面向对象的语言,因此对其行为进行编码的正确方法是定义一个对二进制整数对象执行按位求反的~0b1010方法(我们称之为)。~为了实现这一点,Ruby 解析器(这都是猜测)必须将~obj任何对象解释为obj.~,因此您会得到所有对象的一元运算符。

这只是我的猜测,谁有更权威或更明确的答案,请赐教!

- 编辑 -

正如 @7stud 指出的,该类Regexp使用了它,本质上是与当前作用域中$_接收到的最后一个字符串的正则表达式进行匹配。gets

正如@Daiku 指出的,Fixnums的按位否定也被记录下来

我认为我的解析器解释解决了一个更大的问题:为什么 ruby​​ 允许~作为调用Object#~.