Computer >> 컴퓨터 >  >> 프로그램 작성 >> Ruby

즉석에서 Ruby 열거자 만들기

컬렉션을 열거자로 취급하면 추가 코드를 작성할 필요 없이 #map 및 #reduce와 같은 모든 즐겨찾는 기능을 사용할 수 있습니다. 정말 멋지네요.

옛날에는 열거자를 정의하는 것이 약간 번거로웠습니다. 새 클래스를 만들고 Enumerable 모듈을 포함하고 #each 함수를 정의해야 했습니다.

하지만 Ruby 1.9 이후로 열거자를 즉석에서 정의하는 훨씬 더 가벼운 방법이 있습니다. 살펴보겠습니다.

열거자 클래스 소개

Enumerator 클래스를 사용하면 블록 구문을 사용하여 일회용 열거자를 정의할 수 있습니다. 아래 예에서는 무한 계열의 난수를 반환하는 열거자를 만듭니다.

e = Enumerator.new do |y|
  loop do
    y << rand(10) # The << operator "yields" a value.
  end
end

# Make the enumerator "yield" 10 values, then stop
puts e.first(10).inspect # => [6, 6, 7, 2, 2, 9, 6, 8, 2, 1]

시프트 연산자 <<를 사용하고 있음을 눈치채셨을 것입니다. 이상한 방식으로. 이것은 y.yield의 단축키입니다. 방법. 열거자의 각 항목에 대해 호출합니다. 이 모든 것이 약간 마술처럼 보이더라도 걱정하지 마십시오. 입니다.

컬렉션 크기

컬렉션의 크기를 파악하는 것은 Ruby의 게으른 열거자에게 문제가 됩니다. 컬렉션의 항목을 계산하려면 전체 컬렉션을 로드해야 합니다. 이는 지연 열거자를 사용하는 전체 요점과 반대입니다.

일종의 해결 방법이 있습니다. Enumerator를 생성할 때 컬렉션의 크기를 알고 있다면 제공할 수 있습니다.

# You can pass the length as an argument to the constructor, if you have it
e = Enumerator.new(10) do |y|
  10.times { y << rand }
end

실제 사례

바로 어제 나는 Honeybadge의 새로운 문서 사이트에서 일하고 있었습니다. Jekyll을 사용하여 빌드했으며 <h2>를 기반으로 목차를 만드는 플러그인을 작성했습니다. 및 <h3> 문서의 태그.

어떤 <h3> 태그는 <h2>로 정의된 섹션에 속합니다. 태그. nokogiri를 사용하여 HTML을 구문 분석한 다음 결과 문서를 스캔해야 합니다. 그래서 저는 그 코드를 추상화하여 Enumerator로 만들었습니다. 다음과 같습니다.

def subheadings(el)
  Enumerator.new do |y|
    next_el = el.next_sibling
    while next_el && next_el.name != "h2"
      if next_el.name == "h3"
        y << next_el
      end
      next_el = next_el.next_sibling
    end
  end
end