그게 너무 가져
5068 단어 rubyrubytapasfreebiesidioms
#fetch
메서드 계열에 대한 이 세 번째이자 마지막 에피소드에서는 몇 가지 고급#fetch
사용법에 대해 알아봅니다. 포함: 깊은 가져오기, 폴백 코드에서 누락된 키 이름 사용, #fetch
의 두 인수 형식을 사용하지 않는 이유.Director's commentary: 이 글은 2012년 10월 26일 RubyTapas에 처음 게시되었습니다. 그 이후로
#dig
메서드는 폴백 블록 인수가 부족하지만 내 딥 페칭 요구 사항 중 일부를 대체했습니다.비디오 아래에서 원래 에피소드 스크립트와 코드를 찾으십시오.
소개
이것은 세 번째이며 거의 확실하게 마지막입니다episode on the
#fetch
method. 오늘 저는 #fetch
사용의 몇 가지 고급 측면을 살펴보고자 합니다.#해시 너머 가져오기
우선, 지금까지 해시에 대해 it in the context of
Hash
객체, #fetch
isn’t limited을 시연했다는 점에 주목할 필요가 있습니다. Arrays 에서도 사용할 수 있으며 키가 누락되고 기본 블록이 제공되지 않은 경우 IndexError
대신 KeyError
를 발생시킨다는 점을 제외하면 해시 버전과 매우 유사하게 작동합니다.a = [:x, :y, :z]
a.fetch(3)
# ~> -:2:in `fetch': index 3 outside of array bounds: -3...3 (IndexError)
# ~> from -:2:in `<main>'
#fetch
에서 ENV
pseudo-hash 을 찾을 수도 있습니다. 예를 들어 기본값을 계속 제공하면서 환경 변수를 통해 포트 번호를 사용자 정의할 수 있도록 하는 것과 같이 선택적 구성 값에 매우 유용합니다.port = ENV.fetch('PORT'){ 8080 }.to_i
port # => 8080
중첩 해시의 기본값
경우에 따라 중첩된 해시에서 선택적 값을 가져오고 싶을 수 있습니다. 값이 있는지 여부를 알 수 없을 뿐만 아니라 중첩된 하위 트리가 있는지 여부도 알 수 없습니다. 예를 들어 다음은 몇 가지 구성 데이터입니다.
config1 = {
database: {
type: 'mysql',
host: 'localhost'
}
}
config2 = {} # empty!
누락된 하위 트리에 대한 기본값으로 빈 해시를 사용하여 가져오기 문을 함께 연결하여 이와 같은 데이터를 처리하는 것을 좋아합니다.
config2.fetch(:database){{}}.fetch(:type){'sqlite'}
# => "sqlite"
일반화된 기본 블록
아직 표시하지 않은 한 가지#fetch는 전달된 누락된 키를 생성한다는 것입니다. 다음은 제가 의미하는 바를 보여주는 몇 가지 코드입니다.
{}.fetch(:foo) do |key|
puts "Missing key: #{key}"
end
# >> Missing key: foo
이것이 유용할 수 있는 한 가지 시나리오는 모두 동일한 방식으로 누락된 키를 처리해야 하는 가져오기 호출이 많은 경우입니다. 기본 블록을 하나의 인수를 취하는 lambda으로 정의하고
fetch
에 대한 각 호출에 람다를 전달할 수 있습니다. 이 코드는 사용자에게 누락된 값을 묻는 메시지를 표시합니다.default = ->(key) do
puts "#{key} not found, please enter it: "
gets
end
h = {}
name = h.fetch(:name, &default)
email = h.fetch(:email, &default)
인수가 두 개인 #fetch 형식
#fetch
방법에 이미 익숙하다면 내가 이 비디오에서 두 인수 형식을 사용하지 않은 이유가 궁금할 것입니다. 익숙하지 않은 분들을 위해 블록을 기본값으로 #fetch에 전달하는 대신 두 번째 인수를 전달할 수 있습니다.{}.fetch(:threads, 4) # => 4
이렇게 하면 필요한지 여부에 관계없이 기본값을 평가하는 비용으로 블록을 실행하는 약간의 오버헤드를 피할 수 있습니다. 개인적으로 저는 두 인수 형식을 사용하지 않습니다. 나는 항상 블록 형식을 사용하는 것을 선호합니다. 그 이유는 다음과 같습니다. 우리가 프로그램을 작성 중이고 블록 오버헤드를 피하기 위해 인수가 두 개인 가져오기 형식을 사용한다고 가정해 보겠습니다. 기본값은 여러 곳에서 사용되기 때문에 메서드로 추출합니다.
def default
42 # the ultimate answer
end
answers = {}
answers.fetch("How many roads must a man walk down?", default)
# => 42
나중에
#default
의 구현을 훨씬 더 비싼 계산으로 변경하기로 결정합니다. 반환하기 전에 원격 서비스와 통신해야 하는 것일 수 있습니다.def default
# ...some expensive computation
end
answers = {}
answers.fetch("How many roads must a man walk down?", default)
기본값이
#fetch
에 인수로 전달되면 항상 필요한지 여부가 평가됩니다. 이제 우리의 값비싼#default
코드는 값이 존재하더라도 우리가#fetch
값을 가질 때마다 실행됩니다. 너무 이른 최적화로 인해 #default
방법이 인수로 사용되는 모든 곳에서 잠재적으로 훨씬 더 큰 성능 회귀를 도입했습니다. 블록 형식을 사용했다면 비용이 많이 드는 계산은 실제로 필요할 때만 트리거되었을 것입니다.결론
좋아, #fetch에 대해 충분히! 행복한 해킹!
Reference
이 문제에 관하여(그게 너무 가져), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/avdi/that-s-so-fetch-89k텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)