Was bedeuten die verschiedenen Klammern in Ruby?

84

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.

Tilendor
quelle

Antworten:

70

Es kommt auf den Kontext an:

  1. Wenn Sie alleine oder einer Variablen []zugewiesen sind, werden Arrays und {}Hashes erstellt. z.B

    a = [1,2,3] # an array
    b = {1 => 2} # a hash
  2. []kann als benutzerdefinierte Methode überschrieben werden und wird im Allgemeinen zum Abrufen von Objekten aus Hashes verwendet (die Standardbibliothek wird []als Methode für Hashes eingerichtet, die mit identisch ist fetch).
    Es gibt auch eine Konvention, dass sie in derselben als Klassenmethode verwendet wird So können Sie eine static CreateMethode in C # oder Java verwenden. 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

    Das letzte Beispiel finden Sie in den Ruby Hash-Dokumenten .

  3. Dies ist wahrscheinlich die schwierigste - {}ist auch eine Syntax für Blöcke, jedoch nur, wenn sie an eine Methode AUSSERHALB der Argumente parens übergeben wird.

    Wenn Sie Methoden ohne Parens aufrufen, überprüft Ruby, wo Sie die Kommas setzen, um herauszufinden, wo die Argumente enden (wo die Parens 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
Orion Edwards
quelle
2
Randnotiz: Hash # fetch ist nicht genau Hash # []. {: a => 1 ,: b => 2} .fetch (: c) IndexError: Schlüssel nicht gefunden
tokland
@tokland :cnicht gefunden
yyny
"Es gibt auch eine Konvention, dass es als Klassenmethode verwendet wird, genauso wie Sie eine statische Create-Methode in C # oder Java verwenden könnten." Dies ist genau die Antwort, nach der ich gesucht habe. Auch ein klassisches Beispiel dafür, was ich an Ruby am meisten hasse; Sie müssen Tonnen von obskuren kleinen Tricks kennen, um Ruby-Code zu lesen.
Tony
21

Eine andere, nicht so offensichtliche Verwendung von []ist als Synonym für Proc # call und Method # call. Dies kann beim ersten Auftreten etwas verwirrend sein. Ich denke, das Rationale dahinter 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"]
sris
quelle
9

Im Großen und Ganzen haben Sie Recht. Neben Hashes besteht der allgemeine Stil darin, dass geschweifte Klammern {}häufig für Blöcke verwendet werden, die alle auf eine Zeile passen, anstatt do/ endüber mehrere Zeilen hinweg zu verwenden.

Eckige Klammern []werden in vielen Ruby-Klassen als Klassenmethoden verwendet, einschließlich String, BigNum, Dir und verwirrenderweise Hash. So:

Hash["key" => "value"]

ist genauso gültig wie:

{ "key" => "value" }
John Topley
quelle
3

Die eckigen Klammern [] werden zum Initialisieren von Arrays verwendet. Die Dokumentation zum Initialisierungsfall von [] befindet sich in

ri Array::[]

Die geschweiften Klammern {} werden zum Initialisieren von Hashes verwendet. Die Dokumentation zum Initialisierungsfall von {} befindet sich 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 haben auch 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"

Geschweifte Klammern können auch anstelle von "do ... end" für Blöcke als "{...}" verwendet werden.

Ein weiterer Fall, in dem Sie eckige oder geschweifte Klammern sehen können, sind die speziellen Initialisierer, in denen jedes Symbol verwendet werden kann, z.

%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"
Evgeny
quelle
2

einige 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
James A. Rosen
quelle
2

Beachten Sie, dass Sie die []Methode für Ihre eigenen Klassen definieren können:

class A
 def [](position)
   # do something
 end

 def @rank.[]= key, val
    # define the instance[a] = b method
 end

end
Rogerdpack
quelle
1
Was ist das @rank.?
FeifanZ