Что означают разные скобки в Ruby?

85

В чем разница между {}и в Ruby []?

{} похоже, используется как для блоков кода, так и для хэшей.

Есть []только для массивов?

Документ не очень ясен.

Плиточник
источник

Ответы:

70

Это зависит от контекста:

  1. Когда они []создаются сами по себе или присваиваются переменной, создаются массивы и {}хеши. например

    a = [1,2,3] # an array
    b = {1 => 2} # a hash
    
  2. []может быть переопределен как настраиваемый метод и обычно используется для извлечения вещей из хэшей (стандартная библиотека настраивается []как метод для хешей, который совпадает с fetch)
    Существует также соглашение, что он используется как метод класса в том же как вы могли бы использовать static Createметод на C # или Java. например

    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
    

    См. Последний пример в документации по Ruby Hash .

  3. Это, наверное, самый сложный вариант - {}это тоже синтаксис для блоков, но только когда он передается методу ВНЕ аргументов.

    Когда вы вызываете методы без скобок, Ruby смотрит, где вы ставите запятые, чтобы выяснить, где заканчиваются аргументы (где бы были скобки, если бы вы их набрали).

    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
    
Орион Эдвардс
источник
2
примечание: выборка Hash # не совсем Hash # []. {: a => 1,: b => 2} .fetch (: c) IndexError: ключ не найден
tokland
@tokland :cне найден
yyny
«Существует также соглашение, согласно которому он используется как метод класса так же, как вы могли бы использовать статический метод Create в C # или Java». Это именно тот ответ, который я искал. Также классический пример того, что я больше всего ненавижу в Ruby; чтобы читать код Ruby, нужно знать массу маленьких хитростей.
Тони
21

Другое, не столь очевидное использование []- это синоним вызова Proc # и вызова Method #. Это может немного сбить с толку, когда вы впервые столкнетесь с этим. Я полагаю, что рациональное решение состоит в том, что он больше похож на обычный вызов функции.

Например

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

proc["World"]
meth["Hello",","," ", "World!", "\n"]
срис
источник
9

Вообще говоря, вы правы. Как и хэши, общий стиль состоит в том, что фигурные скобки {}часто используются для блоков, которые могут поместиться в одну строку, вместо использования do/ endв нескольких строках.

Квадратные скобки []используются как методы класса во многих классах Ruby, включая String, BigNum, Dir и, как ни странно, Hash. Так:

Hash["key" => "value"]

действует так же, как:

{ "key" => "value" }
Джон Топли
источник
3

Квадратные скобки [] используются для инициализации массивов. Документация для случая инициализатора [] находится в

ri Array::[]

Фигурные скобки {} используются для инициализации хэшей. Документация для случая инициализатора {} находится в

ri Hash::[]

Квадратные скобки также обычно используются в качестве метода во многих основных классах Ruby, таких как Array, Hash, String и других.

Вы можете получить доступ к списку всех классов, для которых метод "[]" определен с помощью

ri []

у большинства методов также есть метод "[] =", который позволяет назначать вещи, например:

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

Фигурные скобки также могут использоваться вместо «do ... end» в блоках, например, «{...}».

Другой случай, когда вы можете увидеть квадратные или фигурные скобки - это специальные инициализаторы, где можно использовать любой символ, например:

%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"
Евгений
источник
2

несколько примеров:

[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
Джеймс А. Розен
источник
2

Обратите внимание, что вы можете определить []метод для своих собственных классов:

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

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

end
Роджердпак
источник
1
Что такое @rank.?
FeifanZ 05