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?