라라벨 6, 레이지 컬렉션 free

2019-09-11

어제 예고해드린대로 오늘은 라라벨 6에 추가된 레이지 컬렉션(Lazy Collection)을 소개해드리고자 합니다.

왜 쓰는가?


컬렉션이 있는데 왜 레이지 컬렉션이 나왔는지 알면 어떤 때 컬렉션을 쓰고 어떤 때 레이지 컬렉션을 쓸지 판단하는데 도움이 될 겁니다. 컬렉션은 배열을 쉽게 다루게 해주는 도구죠. 어제 살펴본 제너레이터의 핵심 용도는 적은 메모리로 대량의 데이터를 다루는 것이었습니다. 레이지 컬렉션의 핵심 용도도 컬렉션을 사용할 때 제너레이터를 활용하여 적은 메모리로 대량의 데이터를 다루는 것입니다.

레이지 컬렉션 만드는 방법


레이지 컬렉션 인스턴스를 직접 만들 땐 제너레이터 함수를 make() 매서드에 넘겨주면 됩니다.

$lazyCollection = LazyCollection::make(function(){

$handle = fopen('log.txt', 'r');


while (($line = fgets($handle)) !== false) {

yield $line;

}


})

참고로 컬렉션 인스턴스는 생성자에 배열을 넘겨서 만듭니다.

, 2, 3]);레이지 컬렉션은 대부분의 컬렉션 매서드를 사용할 수 있습니다.

쿼리빌더 cursor()


데이터베이스 조회 결과를 레이지 컬렉션으로 만들어야 할 때는 cursor()를 쓰면 됩니다. 쿼리빌더의 cursor() 매서드가 제너레이터를 반환하는 대신 레이지 컬렉션을 반환하도록 변경되었습니다. 대량의 데이터를 적은 메모리로 처리하는 장점은 유지하면서 컬렉션 기능까지 사용할 수 있게 되었다고 보면 될 것 같습니다.


image

매서드


레이지 컬렉션은 컬렉션의 매서드를 대부분 사용할 수 있지만 컬렉션을 변경하는 매서드(예를 들어, shift: 컬렉션의 첫번째 아이템을 반환하고 컬렉션에서 제거, pop: 컬렉션의 마지막 아이템을 반환하고 제거, prepend: 컬렉션 앞에 아이템을 추가)는 사용할 수 없습니다. 제너레이터가 배열을 만들지 않고 개별 아이템을 처리하듯이 레이지 컬렉션은 컬렉션을 만들지 않고 순회하며 개별 아이템을 처리하지 않기 때문에 어찌보면 당연한 이야기네요.


반면 레이지 컬렉션에 추가된 매서드도 있습니다. tapEach() 인데요, each()의 제너레이터 버전이라고 생각하시면 됩니다. each()는 콜백 매서드를 즉시 실행하는 반면, tapEach는 각 항목이 불려질 때 실행합니다.

마치며


아직 사용은 못해봤는데 빨리 써보고 싶네요. 운영 중인 웹사이트들이 대량의 데이터랄게 없는 서비스들이라 별 티는 안 날거 같은게 함정이지만요 ㅠ 나중에 써보고 이슈가 있으면 후기로 공유하겠습니다!


1일 1식 라라벨 52호

2019년 9월 11일


이현석

메쉬 코리아 개발자. 바쁜 팀장님 대신 알려주는 신입 PHP 개발자 안내서를 쓰고, 클린 아키텍처 인 PHP를 번역했습니다. 2020년에 출간될 Laravel Up & Running 2nd Edition을 번역하고 있습니다.