Ruby unary tilde (`~`) method

literals, operators, ruby, syntax

Solution

Using pry to inspect the method:

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

While this is impenetrable to me, it prompted me to look for a C unary `~` operator. One exists: it's the bitwise NOT operator, which flips the bits of a binary integer (`~1010` => `0101`). For some reason this translates to one less than the negation of a decimal integer in Ruby.

More importantly, since ruby is an object oriented language, the proper way to encode the behavior of `~0b1010` is to define a method (let's call it `~`) that performs bitwise negation on a binary integer object. To realize this, the ruby parser (this is all conjecture here) has to interpret `~obj` for any object as `obj.~`, so you get a unary operator for all objects.

This is just a hunch, anyone with a more authoritative or elucidating answer, please enlighten me!

--EDIT--

As @7stud points out, the `Regexp` class makes use of it as well, essentially matching the regex against `$_`, the last string received by `gets` in the current scope.

As @Daiku points out, the bitwise negation of `Fixnum`s is also documented.

I think my parser explanation solves the bigger question of why ruby allows `~` as global unary operator that calls `Object#~`.

Problem

I was goofing around in a pry REPL and found some very interesting behavior: the tilde method. It appears Ruby syntax has a built-in literal unary operator, `~`, just sitting around. This means `~Object.new` sends the message `~` to an instance of `Object`: ``` class Object def ~ puts 'what are you doing, ruby?' end end ~Object.new #=> what are you doing, ruby? ``` This seems really cool, but mysterious. Is Matz essentially trying to give us our own customizable unary operator? The only reference I can find to this in the rubydocs is in the operator precedence notes, where it's ranked as the number one highest precedence operator, alongside `!` and `unary +` This makes sense for unary operators. (For interesting errata about the next two levels of precedence, `**` then `unary -`, check out this question.) Aside from that, no mention of this utility. The two notable references to this operator I can find by searching, amidst the `~=,`!~`, and`~>` questions, are this and this. They both note its usefulness, oddity, and obscurity without going into its history. After I was about to write off `~` as a cool way to provide custom unary operator behavior for your objects, I found a place where its actually used in ruby--fixnum (integers). `~2` returns `-3`. `~-1` returns `1`. So it negates an integer and subtracts one... for some reason? Can anyone enlighten me as purpose of the tilde operator's unique and unexpected behavior in ruby at large?

Original source

Related problems