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

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

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

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

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

Ответов (6)

Решение

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

  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
    

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

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

Hash["key" => "value"]

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

{ "key" => "value" }

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

[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

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

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"

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

Например

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

proc["World"]
meth["Hello",","," ", "World!", "\n"]

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

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

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

end