¿Qué significan los diferentes corchetes en Ruby?

85

En Ruby, ¿cuál es la diferencia entre {}y []?

{} parece usarse tanto para bloques de código como para hashes.

¿Son []solo para matrices?

La documentación no es muy clara.

Tilendor
fuente

Respuestas:

70

Depende del contexto:

  1. Cuando están solos o asignándose a una variable, []crea matrices y {}crea hashes. p.ej

    a = [1,2,3] # an array
    b = {1 => 2} # a hash
    
  2. []se puede anular como un método personalizado, y generalmente se usa para buscar cosas de hashes (la biblioteca estándar se configura []como un método en hash que es el mismo que fetch)
    También existe una convención de que se usa como un método de clase en el mismo forma en que podría usar un static Createmétodo en C # o Java. p.ej

    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
    

    Consulte los documentos de Ruby Hash para ver el último ejemplo.

  3. Este es probablemente el más complicado: {}también es sintaxis para bloques, pero solo cuando se pasa a un método FUERA de los argumentos parens.

    Cuando invoca métodos sin parens, Ruby mira dónde coloca las comas para averiguar dónde terminan los argumentos (dónde habrían estado los parens, si los hubiera escrito)

    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
fuente
2
nota al margen: Hash # fetch no es exactamente Hash # []. {: a => 1,: b => 2} .fetch (: c) IndexError: clave no encontrada
tokland
@tokland :cno encontrado
yyny
"También existe una convención de que se usa como método de clase de la misma manera que podría usar un método Create estático en C # o Java". Esta es exactamente la respuesta que estaba buscando. También un ejemplo clásico de lo que más odio de Ruby; tienes que conocer toneladas de pequeños trucos oscuros para leer el código Ruby.
Tony
21

Otro uso, no tan obvio, de []es como sinónimo de Proc # call y Method # call. Esto puede resultar un poco confuso la primera vez que lo encuentre. Supongo que lo racional detrás de esto es que lo hace parecer más una llamada de función normal.

P.ej

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

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

Hablando en términos generales, tienes razón. Además de los hash, el estilo general es que las llaves {}se usan a menudo para bloques que pueden caber todos en una línea, en lugar de usar do/ enden varias líneas.

Los corchetes []se utilizan como métodos de clase en muchas clases de Ruby, incluidas String, BigNum, Dir y, lo que es bastante confuso, Hash. Entonces:

Hash["key" => "value"]

es tan válido como:

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

Los corchetes [] se utilizan para inicializar matrices. La documentación para el caso de inicializador de [] está en

ri Array::[]

Las llaves {} se utilizan para inicializar hashes. La documentación para el caso de inicializador de {} está en

ri Hash::[]

Los corchetes también se usan comúnmente como método en muchas clases de ruby ​​centrales, como Array, Hash, String y otras.

Puede acceder a una lista de todas las clases que tienen el método "[]" definido con

ri []

la mayoría de los métodos también tienen un método "[] =" que permite asignar cosas, por ejemplo:

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

Las llaves también se pueden usar en lugar de "do ... end" en bloques, como "{...}".

Otro caso en el que puede ver el uso de corchetes o corchetes es en los inicializadores especiales donde se puede usar cualquier símbolo, 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
fuente
2

Algunos ejemplos:

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

Tenga en cuenta que puede definir el []método para sus propias clases:

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

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

end
Rogerdpack
fuente
1
¿Qué es el @rank.?
FeifanZ