Was bedeuten die verschiedenen Klammern in Ruby?
Frage
Was ist in Ruby der Unterschied zwischen {}
Und []
?
{}
scheint sowohl für Codeblöcke als auch für Hashes verwendet zu werden.
Sind []
nur für Arrays?
Die Dokumentation ist nicht sehr klar.
Lösung
Es kommt auf den Kontext an:
Wenn sie alleine sind oder einer Variablen zugewiesen werden,
[]
erstellt Arrays und{}
erstellt Hashes.z.B.a = [1,2,3] # an array b = {1 => 2} # a hash
[]
kann als benutzerdefinierte Methode überschrieben werden und wird im Allgemeinen verwendet, um Dinge aus Hashes abzurufen (die Standardbibliothek richtet sich ein).[]
als Methode für Hashes, die dieselbe ist wiefetch
)
Es gibt auch eine Konvention, dass es als Klassenmethode auf die gleiche Weise verwendet wird, wie Sie a verwenden könntenstatic Create
Methode in C# oder Java.z.B.a = {1 => 2} # create a hash for example puts a[1] # same as a.fetch(1), will print 2 Hash[1,2,3,4] # this is a custom class method which creates a new hash
Siehe den Rubin Hash-Dokumente für das letzte Beispiel.
Das ist wahrscheinlich das Schwierigste -
{}
ist auch eine Syntax für Blöcke, jedoch nur, wenn sie an eine Methode AUSSERHALB der Argumentparens übergeben wird.Wenn Sie Methoden ohne Klammern aufrufen, prüft Ruby, wo Sie die Kommas setzen, um herauszufinden, wo die Argumente enden (wo die Klammern gewesen wären, wenn Sie sie eingegeben hätten).
1.upto(2) { puts 'hello' } # it's a block 1.upto 2 { puts 'hello' } # syntax error, ruby can't figure out where the function args end 1.upto 2, { puts 'hello' } # the comma means "argument", so ruby sees it as a hash - this won't work because puts 'hello' isn't a valid hash
Andere Tipps
Eine andere, nicht so offensichtliche Verwendung von []
ist ein Synonym für Proc#call und Method#call.Wenn Sie es zum ersten Mal sehen, kann es etwas verwirrend sein.Ich denke, der Grund dafür ist, dass es eher wie ein normaler Funktionsaufruf aussieht.
Z.B.
proc = Proc.new { |what| puts "Hello, #{what}!" }
meth = method(:print)
proc["World"]
meth["Hello",","," ", "World!", "\n"]
Im Großen und Ganzen haben Sie Recht.Der allgemeine Stil besteht ebenso wie bei Hashes aus geschweiften Klammern {}
werden häufig für Blöcke verwendet, die alle in eine Zeile passen, anstatt sie zu verwenden do
/end
über mehrere Zeilen hinweg.
Eckige Klammern []
werden in vielen Ruby-Klassen als Klassenmethoden verwendet, darunter String, BigNum, Dir und verwirrenderweise auch Hash.Also:
Hash["key" => "value"]
ist genauso gültig wie:
{ "key" => "value" }
Die eckigen Klammern [ ] werden zum Initialisieren von Arrays verwendet.Die Dokumentation für den Initialisierungsfall [ ] finden Sie in
ri Array::[]
Die geschweiften Klammern {} werden zum Initialisieren von Hashes verwendet.Die Dokumentation für den Initialisierungsfall { } finden Sie in
ri Hash::[]
Die eckigen Klammern werden auch häufig als Methode in vielen Ruby-Kernklassen wie Array, Hash, String und anderen verwendet.
Sie können auf eine Liste aller Klassen zugreifen, für die die Methode „[]“ definiert ist
ri []
Die meisten Methoden verfügen auch über eine „[ ]="-Methode, mit der Dinge zugewiesen werden können, zum Beispiel:
s = "hello world"
s[2] # => 108 is ascii for e
s[2]=109 # 109 is ascii for m
s # => "hemlo world"
Anstelle von „do ...“ können auch geschweifte Klammern verwendet werden.end“ auf Blöcken, als „{ ...}".
Ein weiterer Fall, in dem eckige oder geschweifte Klammern verwendet werden, sind die speziellen Initialisierer, bei denen jedes beliebige Symbol verwendet werden kann, wie zum Beispiel:
%w{ hello world } # => ["hello","world"]
%w[ hello world ] # => ["hello","world"]
%r{ hello world } # => / hello world /
%r[ hello world ] # => / hello world /
%q{ hello world } # => "hello world"
%q[ hello world ] # => "hello world"
%q| hello world | # => "hello world"
ein paar Beispiele:
[1, 2, 3].class
# => Array
[1, 2, 3][1]
# => 2
{ 1 => 2, 3 => 4 }.class
# => Hash
{ 1 => 2, 3 => 4 }[3]
# => 4
{ 1 + 2 }.class
# SyntaxError: compile error, odd number list for Hash
lambda { 1 + 2 }.class
# => Proc
lambda { 1 + 2 }.call
# => 3
Beachten Sie, dass Sie das definieren können []
Methode für Ihre eigenen Klassen:
class A
def [](position)
# do something
end
def @rank.[]= key, val
# define the instance[a] = b method
end
end