Używanie do block vs nawiasy {}
Nowy w ruby, Załóż nowe rękawiczki.
Czy jest jakaś różnica (niejasna lub praktyczna) między poniższymi dwoma fragmentami?
my_array = [:uno, :dos, :tres]
my_array.each { |item|
puts item
}
my_array = [:uno, :dos, :tres]
my_array.each do |item|
puts item
end
Zdaję sobie sprawę, że składnia nawiasu pozwala na umieszczenie bloku w jednej linii
my_array.each { |item| puts item }
Ale poza tym, czy są jakieś przekonujące powody, aby używać jednej składni nad drugą?
4 answers
Ruby cookbook mówi, że składnia nawiasu ma wyższy priorytet niż do..end
Należy pamiętać, że składnia nawiasów ma wyższy priorytet niż zrób..koniec składni. Rozważ następujące kwestie dwa fragmenty kodu:
1.upto 3 do |x|
puts x
end
1.upto 3 { |x| puts x }
# SyntaxError: compile error
Drugi przykład działa tylko wtedy, gdy używane są nawiasy, 1.upto(3) { |x| puts x }
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-01-23 10:17:51
To trochę stare pytanie, ale chciałbym spróbować wyjaśnić nieco więcej na temat {}
i do .. end
Jak to jest powiedziane przed
Składnia nawiasu ma wyższy priorytet niż do..end
Ale jak ta robi różnicę:
method1 method2 do
puts "hi"
end
W tym przypadku, method1 zostanie wywołana z blokiem do..end
, A method2 zostanie przekazana do method1 jako argument! co jest równoważne method1(method2){ puts "hi" }
Ale jeśli powiesz
method1 method2{
puts "hi"
}
Wtedy method2 będzie wywołane z blokiem, wtedy zwrócona wartość zostanie przekazana do method1 jako argument. Co jest równoważne method1(method2 do puts "hi" end)
def method1(var)
puts "inside method1"
puts "method1 arg = #{var}"
if block_given?
puts "Block passed to method1"
yield "method1 block is running"
else
puts "No block passed to method1"
end
end
def method2
puts"inside method2"
if block_given?
puts "Block passed to method2"
return yield("method2 block is running")
else
puts "no block passed to method2"
return "method2 returned without block"
end
end
#### test ####
method1 method2 do
|x| puts x
end
method1 method2{
|x| puts x
}
#### output # # # #
#inside method2
#no block passed to method2
#inside method1
#method1 arg = method2 returned without block
#Block passed to method1
#method1 block is running
#inside method2
#Block passed to method2
#method2 block is running
#inside method1
#method1 arg =
#No block passed to method1
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-10-14 20:13:50
Ogólnie, konwencją jest użycie {}
, gdy wykonujesz małą operację, na przykład wywołanie metody lub porównanie, itp. więc to ma sens:
some_collection.each { |element| puts element }
Ale jeśli masz nieco skomplikowaną logikę, która przechodzi do wielu linii, użyj do .. end
Jak:
1.upto(10) do |x|
add_some_num = x + rand(10)
puts '*' * add_some_num
end
Zasadniczo sprowadza się to do tego, że jeśli twoja logika blokowa przechodzi do wielu linii i nie może być zamontowana w tej samej linii, użyj do .. end
i jeśli twoja logika blokowa jest prosta i tylko prosta / pojedyncza linia kodu, użyj {}
.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-06-29 16:17:31
Istnieją dwa wspólne style wyboru do end
vs. { }
dla bloków w Rubim:
Pierwszy i bardzo popularny styl został spopularyzowany przez Ruby on Rails i opiera się na prostej zasadzie jedno-i wielowierszowej:
- użyj szelek
{ }
dla bloków jednoliniowych - Użyj
do end
dla bloków wielowierszowych
Ma to sens, ponieważ do / end czyta się źle w jednowierszowej, ale w przypadku bloków wielowierszowych pozostawienie zamknięcia }
wiszącego na własnej linii jest niezgodne z Wszystko inne, co używa end
w Rubim, takie jak definicje modułów, klas i metod (def
itd.) i struktur kontrolnych(if
, while
, case
, itd.)
- Użyj
do end
dla bloków proceduralnych - użyj szelek
{ }
do bloków funkcjonalnych
Oznacza to, że gdy blok zostanie oceniony dla jego return wartość , powinna być łańcuchowa, a szelki {}
mają większy sens dla metody łańcuchowania.
Z drugiej strony, gdy blok jest oceniany pod kątem efektów ubocznych , to zwracana wartość nie ma znaczenia, a blok po prostu coś "robi", więc nie ma sensu być przykuty łańcuchem.
To rozróżnienie w składni przekazuje wizualne znaczenie dotyczące oceny bloku i tego, czy powinieneś dbać o jego zwracaną wartość.
Dla przykład, tutaj wartość zwracana bloku jest zastosowana do każdego elementu:
items.map { |i| i.upcase }
Tutaj jednak nie używa się zwracanej wartości bloku. To działa proceduralnie, i robi efekt uboczny z nim:
items.each do |item|
puts item
end
Kolejną zaletą stylu semantycznego jest to, że nie trzeba zmieniać nawiasów, aby wykonać/zakończyć tylko dlatego, że linia została dodana do bloku.
Jako spostrzeżenie, przypadkowo funkcjonalne bloki są często Jednowierszowe, a proceduralne bloki (np. config) są Wielowierszowe. Tak więc podążanie za stylem Weirich kończy się wyglądem prawie takim samym jak styl Rails.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-10-02 23:56:05