Ruby unäre Tilde ('~') Methode

9

Ich habe in einer PRY REPLY herumgespielt und ein sehr interessantes Verhalten gefunden: die Tilde-Methode.

Es scheint, dass die Ruby-Syntax einen eingebauten unären Operator namens ~ hat, der nur herumsteht.

Das bedeutet ~Object.new sendet die Nachricht ~ an eine Instanz von Object :

%Vor%

Das scheint wirklich cool, aber geheimnisvoll. Versucht Matz im Wesentlichen, uns einen eigenen anpassbaren unären Operator zu geben?

Die einzige Referenz, die ich dazu in den Rubydocs finden kann, ist in der Operatorenpräzedenz notes, wo es neben der Nummer ! und unary + als oberster Operator mit der höchsten Priorität eingestuft wird. Dies ist für unäre Operatoren sinnvoll. (Für interessante Errata über die nächsten beiden Rangstufen, ** , dann unary - , check out diese Frage .) Abgesehen davon, keine Erwähnung dieses Nutzens.

Die zwei bemerkenswerten Hinweise auf diesen Operator finde ich bei der Suche, inmitten der ~=, ! ~ , and ~ & gt; ' Fragen, sind das und dies . Sie bemerken beide ihre Nützlichkeit, Kuriosität und Dunkelheit, ohne in ihre Geschichte einzugehen.

Nachdem ich ~ als eine coole Methode abgeschrieben hatte, um ein benutzerdefiniertes Verhalten für unäre Operatoren für Ihre Objekte bereitzustellen, habe ich eine Stelle gefunden, an der sie tatsächlich in ruby ​​- fixnum (Ganzzahlen) verwendet wird.

~2 gibt -3 zurück. ~-1 gibt 1 zurück. Also negiert es eine ganze Zahl und subtrahiert eine ... aus irgendeinem Grund?

Kann mir jemand den Zweck des einzigartigen und unerwarteten Verhaltens des Tilde-Operators in Ruby erklären?

    
Chris Keele 27.07.2013, 01:43
quelle

5 Antworten

2

Verwenden Sie hacken, um die Methode zu überprüfen:

%Vor%

Obwohl dies für mich undurchdringlich ist, hat es mich veranlasst, nach einem C unären ~ -Operator zu suchen. Eine existiert: es ist der bitweise NOT-Operator, der die Bits einer binären Ganzzahl umkehrt ( ~1010 = & gt; 0101 ). Aus irgendeinem Grund wird dies in Ruby um eins weniger als die Negation einer Dezimalzahl.

Noch wichtiger ist, da Ruby eine objektorientierte Sprache ist, ist die richtige Methode, das Verhalten von ~0b1010 zu codieren, eine Methode zu definieren (nennen wir es ~ ), die eine bitweise Negation für ein binäres Ganzzahlobjekt ausführt. Um dies zu realisieren, muss der Rubin-Parser (dies ist hier alles Vermutung) ~obj für jedes Objekt als obj.~ interpretieren, so dass Sie einen unären Operator für alle Objekte erhalten.

Dies ist nur eine Ahnung, jemand mit einer autoritativer oder erhellender Antwort, bitte erleuchte mich!

- BEARBEITEN -

As @ 7stud weist darauf hin, dass die Regexp -Klasse davon Gebrauch macht auch , im Wesentlichen die Regex gegen $_ , die letzte Zeichenfolge von gets im aktuellen Bereich erhalten.

Wie @Daiku betont, ist die bitweise Negation von Fixnum s auch dokumentiert .

Ich denke, meine Parser-Erklärung löst die größere Frage, warum Ruby ~ als globalen unären Operator erlaubt, der Object#~ aufruft.

    
Chris Keele 27.07.2013, 02:12
quelle
3

Für fixnum ist es das Einerkomplement , das binär alle Einsen und Nullen auf den entgegengesetzten Wert umkehrt. Hier ist das Dokument: Ссылка . Um zu verstehen, warum es die Werte in Ihren Beispielen angibt, müssen Sie verstehen, wie negative Zahlen in Binärzahlen dargestellt werden. Warum Ruby das bietet, weiß ich nicht. Zweierkomplement ist im Allgemeinen das, das in modernen Computern verwendet wird. Es hat den Vorteil, dass die gleichen Regeln für grundlegende mathematische Operationen sowohl für positive als auch für negative Zahlen gelten.

    
Daiku 27.07.2013 02:08
quelle
1

Der ~ ist der binäre Einerkomplementoperator in Ruby. Das eine Komplement ist nur das Umdrehen der Bits einer Zahl, so dass die Zahl jetzt arithmetisch negativ ist.

Zum Beispiel ist 2 in 32-Bit (die Größe eines Fixnum) binärs 0000 0000 0000 0010, also wäre ~ 2 gleich 1111 1111 1111 1101 im Einerkomplement.

Wie Sie jedoch bemerkt haben und in diesem Artikel ausführlicher auf Ruby eingehen Die Version des Einerkomplements scheint anders implementiert zu sein, indem sie die Ganzzahl nicht nur negativ macht, sondern auch 1 davon subtrahiert. Ich habe keine Ahnung, warum das so ist, aber es scheint so zu sein.

    
DesAdams 27.07.2013 02:21
quelle
0

Es wird an mehreren Stellen in Spitzhacke 1.8 erwähnt, z. die String-Klasse. In Ruby 1.8.7 funktioniert es jedoch nicht wie angekündigt in der String-Klasse. Es funktioniert für die Regexp-Klasse:

%Vor%

Ähnliches gilt für die String-Klasse.

    
7stud 27.07.2013 02:04
quelle
0
  • ~ (Bignum)
  • ~ (Komplex)
  • ~ (Fixnum)
  • ~ (Regexp)

Jede davon ist in der Dokumentation dokumentiert.

Diese Liste stammt aus der Dokumentation zu Ruby 2.0

Das Verhalten dieser Methode "im Allgemeinen" ist im Grunde genommen alles, was Sie wollen, wie Sie es mit Ihrer Definition einer Methode namens ~ in der Object-Klasse beschrieben haben. Die Verhaltensweisen in den Core-Klassen, die von den Implementierungsbetreuern definiert wurden, scheinen ziemlich gut dokumentiert zu sein, sodass sie für diese Objekte kein unerwartetes Verhalten aufweisen sollten.

    
vgoff 27.07.2013 08:36
quelle

Tags und Links