Ruby에서 자신만의 열거 가능한 객체 작성

9443 단어 programmingruby
이제 Ruby에서 열거 가능한 객체를 작성하는 모범 사례를 보여드리겠습니다. 이 정보는 다른 개체를 포함할 개체를 작성하려는 경우에 유용할 수 있습니다. 예: 당신의 차를 위한 차고; 식료품이 든 장바구니; 메시지가 많은 채팅 등

물론 작업에 Array를 사용할 수 있지만 uniq 동작에 대한 몇 가지 메서드를 추가하려면 고유한 클래스를 작성해야 합니다.

하나의 간단한 예부터 시작하겠습니다. 우리는 자동차를 보관하기 위해 하나의 작은 차고 클래스를 작성합니다. 다음은 단순히 우리 자동차에 대한 정보를 설명하는 Struct입니다.

Car = Struct.new(:name, :color)


그리고 여기 차고를 설명하는 수업이 있습니다.

class MyGarage
  include Enumerable

  def initialize(cars)
    @cars = cars
  end

  def each(&block)
    @cars.each(&block)
  end

  # some methods for uniq behaviour
end

Enumerable -module 및 write each -method를 포함하여 자동차를 반복하는 방법을 설명하는 것은 매우 쉽습니다. 두 대의 자동차로 MyGarage의 인스턴스를 생성해 보겠습니다.

garage = MyGarage.new(
  [Car.new('Nissan', 'red'),
   Car.new('Mazda', 'blue')]
)


우리의 garage -객체에는 Enumerable - module (map/filter/reduce 및 기타)의 모든 동작이 있습니다.

garage.map { |car| puts car.name }
puts garage.any? { |i| i.name == 'Nissan' }
puts garage.filter { |i| i == Car.new('Nissan', 'red') }
puts garage.count
puts garage.first


하지만 인스턴스가 Array - class 의 인스턴스로 필요한 동작이 없기 때문에 만족하지 않습니다. .last , .size 또는 .length 와 같은 메서드가 없습니다. 또한 garage[1] 를 통해 인덱스로 요소를 가져올 수 없습니다.

가장 확실한 방법은 클래스를 다시 작성하고 Array -class에서 상속하는 것입니다.

class MyGarage < Array
  def initialize(arg)
    super(arg)
  end
end


이제 MyGarage 의 각 인스턴스에는 EnumerableArray 로 저장 동작이 있습니다. 불행히도 핵심 클래스에서 상속하는 것은 나쁜 습관입니다. 갑자기 개체가 contverted into an Array이 되거나 디버그하기 어려운 다른 경우를 찾을 수 있습니다. 예시:

puts garage.is_a?(MyGarage)
# true
second_garage = MyGarage.new([Car.new('Nissan', 'blue')])
puts second_garage.is_a?(MyGarage)
# true
new_garage = garage + second_garage
puts new_garage.class
# Array


문제를 해결하는 방법과 자신의 열거 가능한 개체를 작성하는 가장 좋은 방법은 무엇입니까? Enumerable를 사용하고 Array - module을 사용하여 Forwardable에서 필요한 메소드를 위임하는 조합입니다. 최종 코드는 다음과 같습니다.

require 'forwardable'

Car = Struct.new(:name, :color)

class MyGarage
  include Enumerable
  extend Forwardable
  def_delegators :@garage, :size, :length, :[], :empty?, :last, :index

  def initialize(garage)
    @garage = garage
  end

  def each(&block)
    @garage.each(&block)
  end
end

garage = MyGarage.new(
  [Car.new('Nissan', 'red'),
   Car.new('Mazda', 'blue')]
)


결과적으로 MyGarage -class는 Enumerable -module의 모든 메서드를 가지며 필요한 메서드를 Array ( size , length , [] , empty? , last , (47) 및 15649에 위임합니다. ).

좋은 웹페이지 즐겨찾기