Que signifient les différentes parenthèses en Ruby?

85

Dans Ruby, quelle est la différence entre {}et []?

{} semble être utilisé à la fois pour les blocs de code et les hachages.

Sont []uniquement pour les tableaux?

La documentation n'est pas très claire.

Tilendor
la source

Réponses:

70

Ça dépend du contexte:

  1. Lorsqu'ils sont seuls, ou en les affectant à une variable, []crée des tableaux et {}crée des hachages. par exemple

    a = [1,2,3] # an array
    b = {1 => 2} # a hash
    
  2. []peut être remplacée en tant que méthode personnalisée, et est généralement utilisée pour récupérer des éléments à partir des hachages (la bibliothèque standard se configure []comme une méthode sur les hachages, ce qui est identique à fetch)
    Il existe également une convention selon laquelle elle est utilisée comme méthode de classe dans le même façon dont vous pourriez utiliser une static Createméthode en C # ou Java. par exemple

    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
    

    Consultez la documentation Ruby Hash pour ce dernier exemple.

  3. C'est probablement la plus délicate - {}c'est aussi la syntaxe des blocs, mais seulement lorsqu'elle est passée à une méthode EN DEHORS des arguments parens.

    Lorsque vous invoquez des méthodes sans parens, Ruby regarde où vous mettez les virgules pour déterminer où se terminent les arguments (où les parens auraient été, si vous les aviez tapés)

    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
la source
2
note latérale: Hash # fetch n'est pas exactement Hash # []. {: a => 1,: b => 2} .fetch (: c) IndexError: key not found
tokland
@tokland :cintrouvable
yyny
"Il existe également une convention selon laquelle elle est utilisée comme méthode de classe de la même manière que vous pourriez utiliser une méthode Create statique en C # ou Java." C'est exactement la réponse que je cherchais. Aussi un exemple classique de ce que je déteste le plus chez Ruby; vous devez connaître des tonnes de petites astuces obscures pour lire le code Ruby.
Tony
21

Une autre utilisation, pas si évidente, de []est comme synonyme de Proc # call et Method # call. Cela peut être un peu déroutant la première fois que vous le rencontrez. Je suppose que le rationnel derrière cela est que cela ressemble plus à un appel de fonction normal.

Par exemple

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

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

En gros, vous avez raison. En plus des hachages, le style général est que les accolades {}sont souvent utilisées pour les blocs qui peuvent tout tenir sur une seule ligne, au lieu d'utiliser do/ endsur plusieurs lignes.

Les crochets []sont utilisés comme méthodes de classe dans de nombreuses classes Ruby, notamment String, BigNum, Dir et, ce qui est assez déroutant, Hash. Donc:

Hash["key" => "value"]

est tout aussi valable que:

{ "key" => "value" }
John Topley
la source
3

Les crochets [] sont utilisés pour initialiser les tableaux. La documentation pour le cas d'initialisation de [] est dans

ri Array::[]

Les accolades {} sont utilisées pour initialiser les hachages. La documentation du cas d'initialisation de {} se trouve dans

ri Hash::[]

Les crochets sont également couramment utilisés comme méthode dans de nombreuses classes ruby ​​de base, telles que Array, Hash, String et autres.

Vous pouvez accéder à une liste de toutes les classes dont la méthode "[]" est définie avec

ri []

la plupart des méthodes ont également une méthode "[] =" qui permet d'affecter des choses, par exemple:

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

Les accolades peuvent également être utilisées à la place de "do ... end" sur les blocs, comme "{...}".

Un autre cas où vous pouvez voir des crochets ou des accolades utilisés - est dans les initialiseurs spéciaux où n'importe quel symbole peut être utilisé, comme:

%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
la source
2

quelques exemples:

[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
la source
2

Notez que vous pouvez définir la []méthode pour vos propres classes:

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

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

end
rogerdpack
la source
1
Quel est le @rank. ?
FeifanZ