Ruby 一元代字号 (`~` ) 方法

标签 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?

这看起来很酷,但也很神秘。 Matz 本质上是在尝试为我们提供可自定义的一元运算符吗?

我能在 ruby​​docs 中找到的唯一引用是 operator precedence请注意,它与 !unary + 并列为排名第一的最高优先级运算符,这对一元运算符很有意义。 (有关接下来两个优先级别的有趣勘误表,** 然后是 unary -,请查看 this question。)除此之外,没有提及此实用程序。

~=、!~~>` 问题中,我可以通过搜索找到对这个运算符的两个值得注意的引用,是 thisthis .他们都注意到了它的有用性、怪异性和默默无闻,但没有深入了解它的历史。

在我打算注销 ~ 作为为您的对象提供自定义一元运算符行为的一种很酷的方式之后,我发现了它在 ruby​​ 中实际使用的地方 -- fixnum(整数)。

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

谁能告诉我波浪号运算符在 ruby​​ 中独特和意外行为的目的?

最佳答案

使用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;
}

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

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

这只是一个预感,哪位有更权威或者更明确的答案,请赐教!

--编辑--

正如@7stud 指出的那样,Regexpmakes use of it as well ,本质上是将正则表达式与 $_ 进行匹配,这是 gets 在当前范围内接收到的最后一个字符串。

正如@Daiku 指出的那样,Fixnum 的按位求反是 also documented .

我认为我的解析器解释解决了一个更大的问题,即为什么 ruby​​ 允许 ~ 作为调用 Object#~ 的全局一元运算符。

关于Ruby 一元代字号 (`~` ) 方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17893483/

相关文章:

ruby - 重构 Ruby : Converting string array to int array

发布请求中的 Ruby NoMethodError(未定义方法 `map')

scala - Scala 2.10.1 中的新脱糖行为

没有 else 的 Ruby 三元运算符

c++ - 在 C++ 中重载 << 运算符

bash - 为什么 bash -n 和 -z 测试运算符不是 $@ 的反函数

ruby - 如何理解这段寻找最长单词的代码

ruby-on-rails - 如何将换行符转换为 <BR> 标记?

mysql - 触发器中的错误 SQL 语法,MySQL

将 PHP 转换为 JS 的 PHP 代码