[ruby] do 블록 대 중괄호 {} 사용

루비를 처음 접한다면 초보자 장갑을 착용하십시오.

다음 두 스 니펫간에 차이 (모호하거나 실용적인)가 있습니까?

my_array = [:uno, :dos, :tres]
my_array.each { |item|
    puts item
}

my_array = [:uno, :dos, :tres]
my_array.each do |item|
    puts item
end

중괄호 구문을 사용하면 블록을 한 줄에 배치 할 수 있습니다.

my_array.each { |item| puts item }

하지만 그 외에 하나의 구문을 다른 구문보다 사용해야하는 설득력있는 이유가 있습니까?



답변

Ruby 쿡북에 따르면 대괄호 구문이do..end

대괄호 구문은 do..end 구문보다 우선 순위가 높습니다. 다음 두 코드 스 니펫을 고려하십시오.

1.upto 3 do |x|
  puts x
end

1.upto 3 { |x| puts x }
# SyntaxError: compile error

두 번째 예는 괄호가 사용될 때만 작동합니다. 1.upto(3) { |x| puts x }


답변

이것은 조금 오래된 질문하지만 난에 대한 추가 비트를 설명하려고 싶습니다 {}do .. end

전에 말했듯이

대괄호 구문은 do..end보다 우선 순위가 높습니다.

그러나 이것이 어떻게 차이를 만드는지 :

method1 method2 do
  puts "hi"
end

이 경우 method1은의 블록으로 호출 do..end되고 method2는 method1에 인수로 전달됩니다! 이는method1(method2){ puts "hi" }

하지만 당신이 말한다면

method1 method2{
  puts "hi"
}

그러면 method2가 블록과 함께 호출되고 반환 된 값이 method1에 인수로 전달됩니다. 다음과 같습니다.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
}

#### 출력 ####

#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


답변

일반적으로 규칙은 {}메서드 호출이나 비교 등과 같은 작은 작업을 수행 할 때 사용 하는 것이므로 다음과 같이 완벽합니다.

some_collection.each { |element| puts element }

그러나 여러 줄로 이동하는 약간 복잡한 논리가 있으면 다음 do .. end과 같이 사용하십시오 .

1.upto(10) do |x|
  add_some_num = x + rand(10)
  puts '*' * add_some_num
end

기본적으로 블록 논리가 여러 줄로 이동하고 동일한 줄에 맞출 수없는 do .. end경우 를 사용 하고 블록 논리가 단순하고 코드의 단순 / 한 줄이면 {}.


답변

Ruby에서 블록에 대한 선택 do end과 선택을위한 두 가지 일반적인 스타일이 있습니다 { }.

첫 번째이자 매우 일반적인 스타일은 Ruby on Rails에 의해 대중화되었으며 단일 대 다중 라인의 간단한 규칙을 기반으로합니다.

  • { }한 줄 블록에 중괄호 사용
  • 사용 do end멀티 라인 블록

DO / 끝 닫는 떠나, 한 – 라이너에 심하게 읽지 만 여러 줄의 블록 때문에 의미가 있습니다 }자신의 줄에 매달려 다른 모든 것을 그 용도와 일관성이 end같은 모듈, 클래스 및 메소드 정의로 루비 ( def등 .) 및 제어 구조 ( if, while,case 등)

두 번째로 덜 자주 사용되는 스타일은 시맨틱 (Semantic) 또는 ” Weirich Braces ” 로 알려져 있으며 고인이 된 위대한 루비 이스트 Jim Weirich가 제안했습니다.

  • 사용하다 do end 절차 블록
  • { }기능 블록에 중괄호 사용

즉, 블록이 반환 값에 대해 평가 될 때 체인이 가능해야하며{} 중괄호가 메서드 체인에 더 적합합니다.

반면에 블록이 부작용에 대해 평가 될 때 되면 반환 값은 중요하지 않으며 블록은 단지 무언가를 “실행”하기 때문에 연결하는 것이 의미가 없습니다.

구문에서 이러한 구분은 블록 평가에 대한 시각적 의미와 반환 값에 대해 신경을 써야하는지 여부를 전달합니다.

예를 들어, 여기에서 블록의 반환 값은 모든 항목에 적용됩니다.

items.map { |i| i.upcase }

그러나 여기서는 블록의 반환 값을 사용하지 않습니다. 그것은 절차 적으로 운영하고 있어요 하고 그것으로 부작용을 :

items.each do |item|
  puts item
end

시맨틱 스타일의 또 다른 이점은 블록에 줄이 추가 되었기 때문에 수행 / 종료하기 위해 중괄호를 변경할 필요가 없다는 것입니다.

관찰하자면 우연히 기능 블록은 종종 한 줄이며 절차 적 블록 (예 : 구성)은 여러 줄입니다. 따라서 Weirich 스타일을 따르면 Rails 스타일과 거의 동일하게 보입니다.


답변

몇 년 동안 Weirich 스타일을 사용했지만 항상 중괄호를 사용하기 위해이 스타일에서 벗어났습니다 . 블록 스타일의 정보를 사용한 적이 없었고 정의가 모호합니다. 예를 들면 :

date = Timecop.freeze(1.year.ago) { format_date(Time.now) }
customer = Timecop.freeze(1.year.ago) { create(:customer) }

이것은 procudual 또는 기능적입니까?

그리고 줄 수는 내 의견으로는 쓸모가 없습니다. 선이 1 개 이상 있는지, 그리고 선을 추가하거나 제거했다는 이유만으로 스타일을 정확히 변경해야하는 이유를 알고 있습니다.


답변