문제

동일한 결과를주는 두 가지 예제가 있습니다.

블록 :

def self.do_something(object_id)
  self.with_params(object_id) do |params|
    some_stuff(params)
  end
end

def self.with_params(object_id, &block)
  find_object_by_id
  calculate_params_hash
  block.call(params_hash)
end
.

및 방법 :

def self.do_something(object_id)
  some_stuff(self.get_params(object_id))
end

def self.get_params(object_id)
  find_object_by_id
  calculate_params_hash
  params_hash
end
.

두 번째 솔루션은 더 간단 해 보이지만 응용 프로그램 코드에서 첫 번째 사용을 발견했습니다.내 질문은 다음과 같습니다. 첫 번째 첫 번째 상황은 권장됩니까?각각의 장단점은 무엇입니까?

도움이 되었습니까?

해결책

블록과 함수의 주요 차이점은 블록이 호출 함수의 컨텍스트 내에서 을 실행한다는 것입니다.

다음과 같은 예 :

def self.do_something(object_id)
  x = "boogy on"
  self.with_params(object_id) do |params|
    some_stuff(params)
    puts x
  end
end
.

블록 내의 코드는 블록 외부에서 정의 된 변수 x에 액세스 할 수 있습니다. 이것은 폐쇄라고합니다. 두 번째 예제에 따라 기능을 호출하는 경우이 작업을 수행 할 수 없습니다.

블록에 대한 또 다른 흥미로운 점은 외부 함수의 제어 흐름에 영향을 줄 수 있습니다. 그래서 할 수 있습니다 :

def self.do_something(object_id)
  self.with_params(object_id) do |params|
    if some_stuff(params)
        return
    end
  end

  # This wont get printed if some_stuff returns true.
  puts "porkleworkle"
end
.

블록 내의 Some_Stuff 호출이 실제 값을 반환하면 블록이 반환됩니다. 이것은 블록 및 DoSomething 방법 에서 벗어날 것입니다. Porkleworkle 은 출력되지 않습니다.

예제에서는 이들 중 하나에 의존하지 않으므로 함수 호출을 사용하면 훨씬 깨끗합니다.

그러나 이러한 일들을 이용할 수 있도록 블록을 사용하는 것이 많은 상황이 있습니다.

다른 팁

일반적으로 사람들은 다른 코드 내부의 코드 조각을 실행하려는 경우 블록을 사용합니다.예 :

DB.with_shard_for_user(user_id) do |db|
  # perform operations on a user's shard

end # shard is reverted back to original value

File.new(filename) do |file|
  # work with file
end # file is closed automatically

User.transaction do
  # run some operations as a single transaction
end
.

이 블록은 어휘 컨텍스트에서 닫힙니다 (블록이 선언 된 변수를 캡처하고 블록이 호출 될 때 뒤에서 뒤로 옮기십시오).

블록을 수락하는 방법의 개략적 인 구조.

def transaction
  open_transaction # pre- part

  yield if block_given? # run provided code

  commit_transaction # post- part
rescue
  rollback_transaction # handle problems
end
.

첫 번째 예에서 블록의 사용은 아마도 부적절하지 않을 것입니다 (IMHO).명백한 이유가 없어도 너무 복잡합니다.

with_params ()를 호출하면 데이터를 전송할뿐만 아니라 실행할 코드도 제공합니다.with_params () 호출에 다른 블록이 전송되는지 확인하십시오.

...
self.with_params(object_id) do |params|
  some_other_stuff()
  some_stuff(params)
end
...
.

및 어딘가에 :

...
self.with_params(object_id) do |params|
  even_more_stuff(params)
end
...
.

블록이 모두 동일하거나 with_Params ()가 한 곳에서 호출되는 경우 블록을 제거하는 것이 좋습니다.

요약하려면 다음을 수행하십시오. 블록을 사용하십시오. 코드 (블록)의 다른 비트 (블록)와 데이터를 전달하려는 경우 : hey_params,이 데이터 (object_id)를 취하고,이 코드를 실행하십시오 (블록)당신이 그것에있는 동안.

btw 두 예제에서 다른 작업을 수행 중입니다. with_params ()는

를 반환합니다.
some_stuff(params_hash)
. 블록을 평가 한 후

.get_params ()

를 반환합니다.
params_hash
.

블록은 코드에 완전히 의존하지만 함수에는 자체 코드가 있습니다.

그래서, 코드가 상황에 따라 상황을 변화 시키면 블록을 사용하십시오. 그렇지 않은 경우 함수를 작성하고 블록 상자로 사용하십시오.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top