Setzen wir das Mem "Versteckte Funktionen von ..." fort und teilen wir die weniger bekannten, aber nützlichen Funktionen der Programmiersprache Ruby.
Versuchen Sie, diese Diskussion mit Ruby zu begrenzen, ohne Ruby on Rails-Inhalte.
Siehe auch:
- Versteckte Funktionen von C #
- Versteckte Funktionen von Java
- Versteckte Funktionen von JavaScript
- Versteckte Funktionen von Ruby on Rails
- Versteckte Funktionen von Python
(Bitte nur eine versteckte Funktion pro Antwort.)
Danke dir
ruby
hidden-features
Squadette
quelle
quelle
Antworten:
Ab Ruby 1.9 ist Proc # === ein Alias für den Proc # -Aufruf, was bedeutet, dass Proc-Objekte in case-Anweisungen wie den folgenden verwendet werden können:
quelle
Peter Cooper hat eine gute Liste von Ruby-Tricks. Vielleicht ist es sein Favorit, sowohl einzelne Gegenstände als auch Sammlungen aufzählen zu lassen. (Das heißt, behandeln Sie ein Nicht-Sammlungsobjekt als eine Sammlung, die nur dieses Objekt enthält.) Es sieht folgendermaßen aus:
quelle
items
es sich um eine Zeichenfolge handelt, müssen Sie sie nicht mit [*…] einschließen. String.each iteriert nicht wie erwartet über Zeichen. Es kehrt einfach zum Block zurück.Ich weiß nicht, wie versteckt das ist, aber ich fand es nützlich, wenn ich aus einem eindimensionalen Array einen Hash machen muss:
quelle
Hash[ [["apple","red"], ["banana","yellow"] ]
das gleiche Ergebnis erzielt wird.Ein Trick, den ich mag, ist die Verwendung des splat (
*
) - Expanders für andere Objekte als Arrays. Hier ist ein Beispiel für eine Übereinstimmung mit regulären Ausdrücken:Andere Beispiele sind:
quelle
text, number = *"text 555".match(/regexp/)[1..-1]
.text, number = "Something 981".scan(/([A-z]*) ([0-9]*)/).flatten.map{|m| Integer(m) rescue m}
Wow, niemand hat den Flip-Flop-Operator erwähnt:
quelle
i == 3
und nachi != 3
und zu falsei == 15
. Ähnlich wie bei einem Flip-Flop: en.wikipedia.org/wiki/Flip-flop_%28electronics%29Eines der coolen Dinge an Ruby ist, dass Sie Methoden aufrufen und Code an Stellen ausführen können, an denen andere Sprachen die Stirn runzeln würden, z. B. in Methoden- oder Klassendefinitionen.
Um beispielsweise eine Klasse zu erstellen, die bis zur Laufzeit eine unbekannte Oberklasse hat, dh zufällig ist, können Sie Folgendes tun:
Dies verwendet die 1.9-
Array#sample
Methode (siehe nur 1.8.7Array#choice
), und das Beispiel ist ziemlich erfunden, aber Sie können die Leistung hier sehen.Ein weiteres cooles Beispiel ist die Möglichkeit, nicht festgelegte Standardparameterwerte einzugeben (wie dies in anderen Sprachen häufig erforderlich ist):
Das Problem mit dem ersten Beispiel ist natürlich, dass es zur Definitionszeit und nicht zur Aufrufzeit ausgewertet wird. Sobald eine Oberklasse ausgewählt wurde, bleibt diese Oberklasse für den Rest des Programms erhalten.
Im zweiten Beispiel ist
do_something_at
dieat
Variable jedoch bei jedem Aufruf die Zeit, zu der die Methode aufgerufen wurde (na ja, sehr, sehr nahe daran).quelle
require 'activesupport'
Ein weiteres kleines Feature - konvertieren Sie a
Fixnum
in eine beliebige Basis bis zu 36:Und wie Huw Walters kommentiert hat, ist das Umwandeln in die andere Richtung genauso einfach:
quelle
String#to_s(base)
kann verwendet werden, um zurück in eine Ganzzahl zu konvertieren;"1001001100101100000001011010010".to_i(2)
,"499602d2".to_i(16)
Etc alle Rückkehr des OriginalFixnum
.Hashes mit Standardwerten! Ein Array in diesem Fall.
Sehr nützlich bei der Metaprogrammierung.
quelle
Laden Sie die Ruby 1.9-Quelle herunter und geben
make golf
Sie ein Problem ein . Dann können Sie Folgendes tun:Lies das
golf_prelude.c
für mehr nette Dinge, die sich verstecken.quelle
Eine weitere unterhaltsame Ergänzung in der 1.9 Proc-Funktionalität ist Proc # curry, mit der Sie einen Proc, der n Argumente akzeptiert, in einen Proc verwandeln können, der n-1 akzeptiert. Hier wird es mit dem oben erwähnten Proc # === Tipp kombiniert:
quelle
Boolesche Operatoren für nicht boolesche Werte.
&&
und||
Beide geben den Wert des zuletzt ausgewerteten Ausdrucks zurück.
Aus diesem Grund
||=
wird die Variable mit dem Wert aktualisiert, der auf der rechten Seite als Ausdruck zurückgegeben wird, wenn die Variable nicht definiert ist. Dies ist nicht explizit dokumentiert, aber allgemein bekannt.Allerdings
&&=
ist das nicht ganz so bekannt.ist äquivalent zu
Es ist sehr praktisch für destruktive Operationen, die nicht fortgesetzt werden sollten, wenn die Variable undefiniert ist.
quelle
string &&= string + "suffix"
ist gleichbedeutend mitstring = string && string + "suffix"
. Das&&
und die||
Rückgabe ihres zweiten Arguments wird in PickAx, S. 22 besprochen. 154 (Teil I - Facetten von Ruby, Ausdrücke, bedingte Ausführung).Die von Rails bereitgestellte Funktion Symbol # to_proc ist wirklich cool.
Anstatt
Du kannst schreiben:
quelle
require 'activesupport'
da die meisten dieser Helfer tatsächlich von dort stammen.Eine letzte - in Ruby können Sie jedes Zeichen verwenden, mit dem Sie Zeichenfolgen abgrenzen möchten. Nehmen Sie den folgenden Code:
Wenn Sie die doppelten Anführungszeichen in der Zeichenfolge nicht umgehen möchten, können Sie einfach ein anderes Trennzeichen verwenden:
Sie können nicht nur Trennzeichen vermeiden, sondern auch Trennzeichen für schönere mehrzeilige Zeichenfolgen verwenden:
quelle
Ich finde es ziemlich interessant und nicht so bekannt , den Befehl define_method zum dynamischen Generieren von Methoden zu verwenden. Beispielsweise:
Der obige Code verwendet den Befehl 'define_method', um die Methoden "press1" bis "press9" dynamisch zu erstellen. Anstatt alle 10 Methoden einzugeben, die im Wesentlichen denselben Code enthalten, wird der Befehl define method verwendet, um diese Methoden bei Bedarf im laufenden Betrieb zu generieren.
quelle
Verwenden Sie ein Range-Objekt als unendliche Lazy-Liste:
Weitere Informationen hier: http://banisterfiend.wordpress.com/2009/10/02/wtf-infinite-ranges-in-ruby/
quelle
Modulfunktion
Modulmethoden , die als module_function deklariert sind, erstellen Kopien von sich selbst als private Instanzmethoden in der Klasse, die das Modul enthält:
Wenn Sie module_function ohne Argumente verwenden, werden alle Modulmethoden, die nach der Anweisung module_function kommen, automatisch zu module_functions.
quelle
module_function
(2. Weg) ist die Verwendungextend self
(was ziemlich gut aussieht: D)Kurzinjektion wie folgt:
Summe der Reichweite:
quelle
require 'backports'
:-)Warnung: Dieser Artikel wurde zum # 1 Horrendous Hack des Jahres 2008 gewählt . Verwenden Sie ihn daher mit Vorsicht. Vermeiden Sie es eigentlich wie die Pest, aber es ist mit Sicherheit Hidden Ruby.
Superatoren Fügen Sie Ruby neue Operatoren hinzu
Wollten Sie jemals einen supergeheimen Handshake-Operator für eine einzigartige Operation in Ihrem Code? Wie Code Golf spielen? Versuchen Sie es mit Operatoren wie - ~ + ~ - oder <---. Der letzte wird in den Beispielen zum Umkehren der Reihenfolge eines Elements verwendet.
Ich habe nichts mit dem Superators-Projekt zu tun, außer es zu bewundern.
quelle
Ich bin zu spät zur Party, aber:
Sie können problemlos zwei Arrays gleicher Länge in einen Hash umwandeln, wobei ein Array die Schlüssel und das andere die Werte liefert:
(Dies funktioniert, weil Array # zip die Werte der beiden Arrays "komprimiert":
Und Hash [] kann genau ein solches Array aufnehmen. Ich habe Leute gesehen, die das auch gemacht haben:
Was das gleiche Ergebnis liefert, aber Splat und Flatten sind völlig unnötig - vielleicht waren sie nicht in der Vergangenheit?)
quelle
Automatische Belebung von Hashes in Ruby
Das kann verdammt praktisch sein.
quelle
module InfHash; def self.new; Hash.new {|h,k| h[k] = Hash.new(&h.default_proc)}; end; end
Ein Array zerstören
Wo:
Mit dieser Technik können wir eine einfache Zuweisung verwenden, um die genauen Werte aus einem verschachtelten Array beliebiger Tiefe zu erhalten.
quelle
Class.new()
Erstellen Sie zur Laufzeit eine neue Klasse. Das Argument kann eine Klasse sein, von der abgeleitet werden kann, und der Block ist der Klassenkörper. Vielleicht möchten Sie auch einen Blick darauf werfen
const_set/const_get/const_defined?
, ob Ihre neue Klasse ordnungsgemäß registriert ist, damitinspect
ein Name anstelle einer Nummer ausgedruckt wird.Nicht etwas, das Sie jeden Tag brauchen, aber sehr praktisch, wenn Sie es tun.
quelle
MyClass = Class.new Array do; def hi; 'hi'; end; end
scheint äquivalent zu seinclass MyClass < Array; def hi; 'hi'; end; end
.Erstellen Sie ein Array von fortlaufenden Zahlen:
setzt x auf [0, 1, 2, 3, 4, 5]
quelle
*
) - Operator ruft grundsätzlichto_a
trotzdem auf.Ein Großteil der Magie, die Sie in Rubyland sehen, hat mit Metaprogrammierung zu tun, bei der einfach Code geschrieben wird, der Code für Sie schreibt. Ruby's
attr_accessor
,attr_reader
undattr_writer
sind alle einfache Metaprogrammierungen, da sie zwei Methoden in einer Zeile nach einem Standardmuster erstellen. Rails führt eine Menge Metaprogrammierung mit ihren Beziehungsmanagementmethoden wiehas_one
und durchbelongs_to
.Es ist jedoch ziemlich einfach, eigene Metaprogrammier-Tricks zu erstellen
class_eval
, mit denen dynamisch geschriebener Code ausgeführt wird.Im folgenden Beispiel kann ein Wrapper-Objekt bestimmte Methoden an ein internes Objekt weiterleiten:
Die Methode
Wrapper.forwards
Symbole für die Namen der Methoden und speichert sie immethods
Array. Dann verwenden wir für jeden der angegebenendefine_method
erstellen Methoden eine neue Methode, deren Aufgabe es ist, die Nachricht einschließlich aller Argumente und Blöcke mitzusenden.Eine großartige Quelle für Metaprogrammierungsprobleme ist, warum der Lucky Stiff "Metaprogrammierung klar sehen" .
quelle
Verwenden Sie für Fallvergleiche alles, worauf reagiert
===(obj)
wird:Module
(und damitClass
),Regexp
,Date
und viele andere Klassen definieren eine Instanzmethode: === (andere), und alle verwendet werden können.Vielen Dank an Farrel für die Erinnerung an
Proc#call
das AliasingProc#===
in Ruby 1.9.quelle
Die "Ruby" -Binärdatei (zumindest MRTs) unterstützt viele der Schalter, die Perl-Einzeiler sehr beliebt gemacht haben.
Bedeutende:
put
s am Ende jeder SchleifeniterationEinige Beispiele:
Fühlen Sie sich frei, "Ruby One-Liner" und "Perl One-Liner" für Tonnen mehr brauchbare und praktische Beispiele zu googeln. Es ermöglicht Ihnen im Wesentlichen, Rubin als ziemlich starken Ersatz für awk und sed zu verwenden.
quelle
Die send () -Methode ist eine Allzweckmethode, die für jede Klasse oder jedes Objekt in Ruby verwendet werden kann. Wenn nicht überschrieben, akzeptiert send () eine Zeichenfolge und ruft den Namen der Methode auf, deren Zeichenfolge übergeben wird. Wenn der Benutzer beispielsweise auf die Schaltfläche "Clr" klickt, wird die Zeichenfolge "press_clear" an die Methode "send ()" gesendet und die Methode "press_clear" aufgerufen. Die send () -Methode ermöglicht eine unterhaltsame und dynamische Möglichkeit, Funktionen in Ruby aufzurufen.
Ich spreche mehr über diese Funktion in Blogging Shoes: The Simple-Calc Application
quelle
Machen Sie sich eine Klasse oder ein Modul zum Narren und sagen Sie, dass etwas erforderlich ist, das es wirklich nicht benötigt:
Dies ist zum Beispiel nützlich, wenn A erforderlich ist, für das wiederum B erforderlich ist, wir jedoch kein B in unserem Code benötigen (und A es auch nicht über unseren Code verwendet):
Zum Beispiel Backgroundrb's
bdrb_test_helper requires
'test/spec'
, aber Sie verwenden es überhaupt nicht, also in Ihrem Code:quelle
Fixnum#to_s(base)
kann in manchen Fällen sehr nützlich sein. Ein solcher Fall ist das Erzeugen zufälliger (Pseudo-) eindeutiger Token durch Konvertieren einer Zufallszahl in einen String unter Verwendung der Basis von 36.Token der Länge 8:
Token der Länge 6:
quelle
Definieren einer Methode, die eine beliebige Anzahl von Parametern akzeptiert und nur alle verwirft
Die obige
hello
Methode muss nurputs
"hello"
auf dem Bildschirm angezeigt werden,super
aber da die Oberklasse auchhello
Parameter definiert, muss sie dies auch tun. Da sie jedoch die Parameter selbst nicht verwenden muss, muss sie ihnen keinen Namen geben.quelle