Що означають різні дужки в 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. Це, мабуть, найскладніше - {}це також синтаксис для блоків, але лише тоді, коли він передається методу ВНЕ поза аргументами аргументів.

    Коли ви викликаєте методи без парен, Рубі переглядає, куди ви ставите коми, щоб зрозуміти, де закінчуються аргументи (де б були парени, якби ви їх ввели)

    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 # fetch - це не зовсім Hash # []. {: a => 1,: b => 2} .fetch (: c) IndexError: ключ не знайдено
Tokland

@tokland :cне знайдено
yyny

"Існує також умова, що він використовується як метод класу так само, як ви можете використовувати статичний метод Create у C # або Java." Це саме та відповідь, яку я шукав. Також класичний приклад того, що я найбільше ненавиджу в Рубі; Ви повинні знати масу незрозумілих маленьких хитрощів, щоб читати код Ruby.
Тоні

21

Іншим, не таким очевидним, використання []є як синонім виклику Proc # та методу # виклику. Це може трохи заплутати при першій зустрічі. Я думаю, раціональне, що стоїть за цим, полягає в тому, що це робить його більш схожим на звичайний виклик функції.

Напр

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::[]

Квадратні дужки також часто використовуються як метод у багатьох основних класах рубіну, таких як 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
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.