Co oznaczają różne nawiasy w Rubim?

85

Jaka jest różnica między {}i w Rubim []?

{} wydaje się być używany zarówno dla bloków kodu, jak i skrótów.

[]tylko dla tablic?

Dokumentacja nie jest zbyt jasna.

Tilendor
źródło

Odpowiedzi:

70

To zależy od kontekstu:

  1. Samodzielnie lub przypisując do zmiennej, []tworzy tablice i {}tworzy skróty. na przykład

    a = [1,2,3] # an array
    b = {1 => 2} # a hash
    
  2. []może być nadpisana jako metoda niestandardowa i jest generalnie używana do pobierania rzeczy z hashów (standardowa biblioteka ustawia się []jako metodę na hashach, która jest taka sama jak fetch)
    Istnieje również konwencja, że ​​jest używana jako metoda klas w tym samym sposób, w jaki możesz użyć static Createmetody w C # lub Javie. na przykład

    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
    

    Ostatni przykład można znaleźć w dokumentacji Ruby Hash .

  3. Jest to prawdopodobnie najtrudniejsza {}metoda - jest również składnią bloków, ale tylko wtedy, gdy jest przekazywana do metody POZA argumentami parens.

    Kiedy wywołujesz metody bez parenów, Ruby sprawdza, gdzie umieściłeś przecinki, aby dowiedzieć się, gdzie kończą się argumenty (gdzie byłyby pareny, gdybyś je wpisał)

    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
źródło
2
uwaga dodatkowa: Hash # fetch nie jest dokładnie Hash # []. {: a => 1,: b => 2} .fetch (: c) IndexError: key not found
tokland,
@tokland :cnot found
yyny,
„Istnieje również konwencja, że ​​jest używana jako metoda klasowa w taki sam sposób, w jaki można używać statycznej metody Create w C # lub Javie”. To jest dokładnie odpowiedź, której szukałem. Również klasyczny przykład tego, czego najbardziej nienawidzę w Rubim; aby czytać kod Rubiego, musisz znać mnóstwo mało znanych sztuczek.
Tony
21

Innym, nie tak oczywistym, użyciem []jest synonim wywołania Proc # i wywołania metody #. Może to być trochę zagmatwane, gdy napotkasz go po raz pierwszy. Myślę, że racjonalne jest to, że wygląda to bardziej jak normalne wywołanie funkcji.

Na przykład

proc = Proc.new { |what| puts "Hello, #{what}!" }
meth = method(:print)

proc["World"]
meth["Hello",","," ", "World!", "\n"]
sris
źródło
9

Ogólnie rzecz biorąc, masz rację. Oprócz skrótów, ogólny styl polega na tym, że nawiasy klamrowe {}są często używane do bloków, które można zmieścić w jednym wierszu, zamiast używać do/ endw kilku wierszach.

Nawiasy kwadratowe []są używane jako metody klas w wielu klasach Ruby, w tym w String, BigNum, Dir i, co jest mylące, Hash. Więc:

Hash["key" => "value"]

jest tak samo ważne jak:

{ "key" => "value" }
John Topley
źródło
3

Nawiasy kwadratowe [] służą do inicjalizacji tablic. Dokumentacja dotycząca przypadku inicjatora [] jest w formacie

ri Array::[]

Nawiasy klamrowe {} służą do inicjalizacji skrótów. Dokumentacja dotycząca przypadku inicjatora {} jest dostępna

ri Hash::[]

Nawiasy kwadratowe są również powszechnie używane jako metoda w wielu podstawowych klasach ruby, takich jak Array, Hash, String i inne.

Możesz uzyskać dostęp do listy wszystkich klas, dla których zdefiniowano metodę „[]”

ri []

większość metod ma również metodę „[] =”, która umożliwia przypisywanie rzeczy, na przykład:

s = "hello world"
s[2]     # => 108 is ascii for e
s[2]=109 # 109 is ascii for m
s        # => "hemlo world"

Nawiasy klamrowe mogą być również używane zamiast „do ... end” w blokach, jako „{...}”.

Innym przypadkiem, w którym można zobaczyć nawiasy kwadratowe lub nawiasy klamrowe, są specjalne inicjatory, w których można użyć dowolnego symbolu, takiego jak:

%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
źródło
2

kilka przykładów:

[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
źródło
2

Pamiętaj, że możesz zdefiniować []metodę dla swoich własnych klas:

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

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

end
rogerdpack
źródło
1
Co to jest @rank.?
FeifanZ