O que significam os diferentes colchetes em Ruby?

85

Em Ruby, qual é a diferença entre {}e []?

{} parece ser usado para blocos de código e hashes.

São []apenas para matrizes?

A documentação não é muito clara.

Tilendor
fonte

Respostas:

72

Depende do contexto:

  1. Quando por conta própria ou atribuindo a uma variável, []cria arrays e {}cria hashes. por exemplo

    a = [1,2,3] # an array
    b = {1 => 2} # a hash
    
  2. []pode ser sobrescrito como um método personalizado, e geralmente é usado para buscar coisas de hashes (a biblioteca padrão configura []como um método em hashes que é o mesmo que fetch)
    Há também uma convenção de que é usado como método de classe no mesmo maneira você pode usar um static Createmétodo em C # ou Java. por exemplo

    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
    

    Veja a documentação do Ruby Hash para esse último exemplo.

  3. Este é provavelmente o mais complicado - {}também é sintaxe para blocos, mas apenas quando passado para um método FORA dos parênteses dos argumentos.

    Quando você invoca métodos sem parênteses, Ruby olha onde você colocou as vírgulas para descobrir onde os argumentos terminam (onde os parênteses estariam, se você os tivesse digitado)

    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
fonte
2
observação lateral: Hash # fetch não é exatamente Hash # []. {: a => 1,: b => 2} .fetch (: c) IndexError: chave não encontrada
tokland
@tokland :cnão encontrado
yyny
"Também existe uma convenção de que é usado como um método de classe da mesma maneira que você pode usar um método Create estático em C # ou Java." Esta é exatamente a resposta que eu estava procurando. Também é um exemplo clássico do que mais odeio em Ruby; você tem que saber muitos pequenos truques obscuros para ler o código Ruby.
Tony
22

Outro uso, não tão óbvio, de []é como sinônimo de Proc # call e Method # call. Isso pode ser um pouco confuso na primeira vez que você o encontrar. Eu acho que o racional por trás disso é que faz com que pareça mais uma chamada de função normal.

Por exemplo

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

proc["World"]
meth["Hello",","," ", "World!", "\n"]
sris
fonte
9

Em termos gerais, você está correto. Assim como hashes, o estilo geral é que as chaves {}são freqüentemente usadas para blocos que podem caber todos em uma linha, em vez de usar do/ endem várias linhas.

Colchetes []são usados ​​como métodos de classe em muitas classes Ruby, incluindo String, BigNum, Dir e, para confusão, Hash. Então:

Hash["key" => "value"]

é tão válido quanto:

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

Os colchetes [] são usados ​​para inicializar matrizes. A documentação para o caso de inicializador de [] está em

ri Array::[]

As chaves {} são usadas para inicializar hashes. A documentação para o caso de inicializador de {} está em

ri Hash::[]

Os colchetes também são comumente usados ​​como um método em muitas classes centrais de ruby, como Array, Hash, String e outras.

Você pode acessar uma lista de todas as classes que têm o método "[]" definido com

ri []

a maioria dos métodos também tem um método "[] =" que permite atribuir coisas, por exemplo:

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

Parênteses encaracolados também podem ser usados ​​em vez de "do ... end" em blocos, como "{...}".

Outro caso onde você pode ver os colchetes ou colchetes usados ​​- é nos inicializadores especiais onde qualquer símbolo pode ser usado, como:

%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
fonte
2

alguns exemplos:

[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
fonte
2

Observe que você pode definir o []método para suas próprias classes:

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

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

end
rogerdpack
fonte
1
O que é @rank.?
FeifanZ