새해 복 많이 받으세요! Ruby Magic에 다시 오신 것을 환영합니다. 이번 겨울 에피소드에서는 바인딩(binding)과 스코프(scope)를 깊이 파헤쳐 보겠습니다. 스키를 신고 저희와 함께 숲속 깊은 곳으로 떠나보시죠. 지난 호에서는 블록, 프록(proc), 람다(lambda)를 비교하며 Ruby의 클로저(closure)를 살펴봤습니다. 세 가지 타입의 차이점 외에도 클로저를 정의하는 핵심 요소가 무엇인지 함께 다뤘습니다. 클로저는 환경(environment)을 가진 일급 함수(first-class function)입니다.
개발자들이 GraphQL의 놀라운 장점을 극찬하는 이야기를 들어보셨을 겁니다. 이 시리즈는 기술을 직접 사용해 보면서 배우는 방식을 지향하는데요, 이번 글에서는 GraphQL을 활용한 예제 애플리케이션을 단계별로 살펴보겠습니다. GraphQL이란 무엇인가? GraphQL은 API를 구축하기 위한 쿼리 언어이자 런타임입니다. 개발 스택에서 REST API와 비슷한 위치를 차지하지만, 훨씬 더 유연하다는 점이 특징입니다. REST와 달리 GraphQL은 응답 형식과 내용을 클라이언트 측에서 직접 지정할 수 있습니다. SQL의 SELEC
Ruby Magic의 새로운 에피소드에 오신 것을 환영합니다! 이번 호에서는 두 개발자(안녕하세요, Maud!) 사이의 논쟁에서 출발한 주제인 메타클래스(metaclass)를 다룹니다.메타클래스를 살펴보는 과정에서 Ruby에서 클래스 메서드와 인스턴스 메서드가 실제로 어떻게 동작하는지 이해하게 될 것입니다. 아울러 명시적인 definee를 전달해 메서드를 정의하는 방식과 class << self, instance_eval을 사용하는 방식의 차이점도 함께 알아보겠습니다. 그럼 시작해볼까요?클래스 인스턴스와 인스턴스 메서드R
오늘 포스트에서는 Ruby의 #dup과 #clone 메서드를 자세히 살펴보겠습니다. 먼저 이 주제에 관심을 갖게 된 실제 사례부터 시작하고, 이어서 Ruby에서 #dup이 어떻게 구현되어 있는지, 그리고 #clone과 어떻게 다른지 깊이 있게 알아볼 것입니다. 마지막으로 직접 #dup 메서드를 구현해 보며 마무리하겠습니다. 시작해 볼까요!#dup을 사용하게 된 계기NGO 단체의 기부 캠페인 구축을 전문으로 하는 회사에서 일할 때, 저는 기존 캠페인을 복사해서 새 캠페인을 만드는 작업을 자주 해야 했습니다. 예를 들어 2018년 캠페
Ruby는 재미있는 언어일 뿐만 아니라 훌륭한 표준 라이브러리도 함께 제공합니다. 그중 일부는 잘 알려지지 않아 마치 숨겨진 보석과 같습니다. 오늘은 게스트 작가 Michael Kohl이 자신이 특히 좋아하는 기능 중 하나인 StringScanner를 소개합니다.Ruby의 숨겨진 보석: StringScannerOpenStruct나 Set 같은 자료구조부터 CSV 파싱, 벤치마킹까지, 서드파티 젬(gem)을 설치하지 않고도 꽤 많은 작업을 처리할 수 있습니다. 하지만 Ruby의 기본 설치에 포함되어 있음에도 불구하고 잘 알려지지 않아
이 글에서는 객체 마샬링(Object Marshalling)에 대해 깊이 있게 다뤄보겠습니다. 마샬링이 무엇인지 설명하고, Marshal 모듈을 살펴본 뒤 실제 예제를 통해 확인해 보겠습니다. 나아가 _dump와 self._load 메서드를 비교하며 한 단계 더 들어가 보겠습니다. 그럼 시작해 볼까요!객체 마샬링이란 무엇일까요?코드를 작성하다 보면 객체를 저장한 뒤 다른 프로그램으로 전송하거나, 다음 프로그램 실행 시 재사용하고 싶은 경우가 있습니다. 대표적인 예가 Sidekiq입니다. Ruby on Rails 애플리케이션에서 Si
이번 글에서는 재미 삼아 아주 기본적인 백그라운드 작업 처리 시스템을 직접 구현해 보겠습니다. 이 과정에서 Sidekiq처럼 널리 쓰이는 백그라운드 처리 시스템의 내부 동작 원리를 들여다보며 여러 가지를 배울 수 있을 것입니다. 물론 여기서 만들 결과물은 실제 운영 환경(프로덕션)에서 사용할 목적이 전혀 아닙니다.애플리케이션에 하나 이상의 웹사이트에 접속해서 페이지 제목(title)을 추출하는 작업이 있다고 상상해 봅시다. 해당 웹사이트들의 응답 속도는 우리가 통제할 수 없기 때문에, 이 작업은 메인 스레드(웹 애플리케이션이라면 현
끊임없이 성장하는 올인원 APM(애플리케이션 성능 모니터링) 서비스로서, 우리는 AppSignal이 늘어나는 트래픽을 감당할 수 있도록 만드는 데 많은 시간을 쏟고 있습니다. 보통 우리는 그 방법에 대해 이야기하지 않습니다. 블로그에는 루비 내부 동작의 흥미로운 이야기나 엘릭서로 하는 기발한 실험 글은 가득해도, AppSignal 자체가 어떻게 돌아가는지는 다루지 않았으니까요.하지만 이번에는 지난 몇 년간 스택에 적용한 큰 변화들을 공유하려 합니다. 덕분에 매달 두 자릿수 십억 건에 달하는 요청을 실시간으로 처리할 수 있게 되었으니
오늘은 Ruby 표준 라이브러리의 숨겨진 보석들을 탐험하는 시간으로, 위임(Delegation)에 대해 알아보겠습니다.아쉽게도 이 용어는 다른 많은 용어들처럼 오랜 세월 동안 그 의미가 다소 모호해졌고, 사람마다 다르게 해석하고 있습니다. 위키백과에 따르면:위임(Delegation)은 한 객체(수신자)의 멤버(속성 또는 메서드)를 다른 원본 객체(발신자)의 맥락에서 평가하는 것을 의미한다. 위임은 발신 객체를 수신 객체에 전달함으로써 명시적으로 수행할 수 있으며, 이는 어떤 객체지향 언어에서도 가능하다. 또는 언어의 멤버 탐색 규칙
짐을 챙겨주세요! 오늘은 Ruby의 조상 체인(Ancestor Chain) 끝까지 올라가는 여정을 떠납니다. 하나의 메서드 호출이 체인을 따라 어떻게 전달되는지 추적하고, 메서드가 존재하지 않을 때 어떤 일이 벌어지는지도 확인해 보겠습니다. 그리고 모험을 좋아하는 우리답게 거기서 멈추지 않고 BasicObject#method_missing까지 직접 오버라이딩해 볼 것입니다. 잘 따라오신다면 실용적인 예제도 함께 다룰 수 있을 겁니다. 물론 장담하진 않지만요. 자, 출발합니다! 조상 체인(Ancestor Chain) Ruby에서
Ruby Magic에 다시 오신 것을 환영합니다! 1년 전 우리는 배열, 범위(Range), 해시 같은 열거 가능한 객체를 다룰 때 사용하는 메서드를 제공하는 Ruby의 Enumerable 모듈에 대해 배웠습니다.당시에는 LinkedList 클래스를 만들어 #each 메서드를 구현함으로써 객체를 열거 가능하게 만드는 방법을 살펴보았습니다. Enumerable 모듈을 포함(include)시키면 직접 구현하지 않고도 연결 리스트에서 #count, #map, #select 같은 메서드를 호출할 수 있었습니다.열거자(Enumerable)를
스쿠버 다이빙 장비를 점검하고 스텐실을 챙기세요. 오늘은 템플릿(Template)의 세계로 함께 다이빙해 보겠습니다!웹 페이지를 렌더링하거나 이메일을 생성하는 대부분의 소프트웨어는 템플릿 기법을 사용해 가변 데이터를 텍스트 문서에 삽입합니다. 문서의 전체 구조는 데이터가 들어갈 자리에 플레이스홀더(placeholder)를 남겨 둔 정적 템플릿으로 구성되고, 사용자 이름이나 웹 페이지 콘텐츠 같은 가변 데이터는 렌더링 시점에 플레이스홀더를 대체하면서 들어갑니다.이번 글에서는 다양한 프로그래밍 언어에서 사용할 수 있는 템플릿 언어인 M
Ruby 템플릿(Templating) 시리즈에 돌아왔습니다. 지난 시간에 렉서(lexer)를 완성했으니, 이제 다음 단계인 파서(parser)로 넘어가 보겠습니다.지난 글에서는 문자열 보간(string interpolation)을 살펴본 후, 나만의 템플릿 언어를 만드는 작업에 착수했습니다. 그 첫걸음으로 템플릿을 읽어 토큰(token) 스트림으로 변환하는 렉서를 구현했죠. 오늘은 이와 짝을 이루는 파서를 직접 구현하면서, 약간의 언어 이론도 함께 맛보겠습니다.그럼 시작해 볼까요?추상 구문 트리(Abstract Syntax Tree
생각을 코드로 옮길 때 우리는 대부분 가장 익숙한 메서드를 사용합니다. 떠오르는 대로 손이 먼저 움직이는 메서드들이죠. 정리가 필요한 문자열을 마주하면, 고민할 새 없이 결과를 만들어낼 익숙한 메서드를 입력하고 있습니다. 이렇게 무의식적으로 입력되는 메서드는 대개 가장 범용적인 루비 메서드입니다. 다른 어떤 메서드보다 더 자주 읽고 쓰기 때문입니다. 예컨대 #gsub은 문자열 안의 문자를 치환하는 대표적인 범용 메서드입니다. 하지만 루비에는 표준적인 작업을 위해 더 특화된 편의 메서드가 훨씬 많습니다. 저는 루비의 풍부한 관용 표현
재미있는 퀴즈로 글을 시작해 보겠습니다. AppSignal이 Ruby 애플리케이션에서 추적하는 가장 흔한 에러가 무엇일까요?많은 분들이 NoMethodError라고 답하셨을 것입니다. 이 예외는 객체에 존재하지 않는 메서드를 호출할 때 발생합니다. 가끔은 메서드 이름의 오타 때문에 생기기도 하지만, 대부분은 잘못된 타입의 객체에 메서드를 호출했기 때문입니다. 그리고 그 주범은 십중팔구 예상치 못한 nil입니다. Ruby 개발자로서 이런 에러의 발생 빈도를 줄일 방법은 없을까요?타입 시스템이 해결책일까?텍스트 에디터나 프로그래밍 언어
안녕하세요, 자식들과 부모님 여러분... 아니, 루비스트(Rubyist) 여러분! 이전 글에서는 조상 체인(ancestry chain)을 파헤쳐 봤는데요. 오늘은 상속이라는 육아 주제를 한층 더 깊이 들어가 보겠습니다. inherited 훅 메서드를 자세히 살펴보고, 나아가 상속 자체를 막는 방법까지 알아봅니다.자식 클래스가 상속될 때: inherited 훅 메서드먼저 부모 관계, 즉 상속이 선언되는 순간부터 살펴보겠습니다. 루비는 어떤 클래스가 다른 클래스의 부모로 선언될 때, 해당 부모 클래스와 상호작용할 수 있는 깔끔한 방법을
커피 위에 스트룹와펠을 올려 따뜻하게 녹여 두셨나요? 오늘은 스트룹와펠의 두 반쪽을 붙여 주는 그 끈적한 스트룹(시럽)처럼, 지금까지 만든 조각들을 하나로 합쳐 보려 합니다. 이 시리즈의 앞선 두 편에서는 Lexer와 Parser를 구웠습니다. 이제 마지막 재료인 Interpreter를 더하고, 그 위에 스트룹을 부어 전체를 하나로 연결해 보겠습니다.재료 준비하기자, 베이킹을 위해 주방을 정리하고 재료를 테이블에 꺼내 봅시다. 인터프리터가 제 역할을 하려면 두 가지 재료, 즉 두 가지 정보가 필요합니다. 바로 앞서 생성한 추상 구문
Sidekiq의 성능을 최적화하거나 모니터링하는 방법에 대한 문의를 자주 받습니다. 모니터링은 저희의 전문 분야이지만, Sidekiq 성능 최적화는 완전히 다른 차원의 이야기입니다. 사실 최적화는 결코 간단하지 않지만, 겉보기에 단순해 보이는 답부터 하나씩 살펴보겠습니다.속도를 높이는 두 가지 방법처리 속도를 높이는 방법은 크게 두 가지입니다. 하나는 더 큰 작업(job)을 수행하는 것이고(메모리나 IO를 더 많이 사용하거나 로직이 복잡해질 수 있음), 다른 하나는 동시성(concurrency) 설정이나 워커(worker) 수를 조
안녕하세요, 스트루프와펠(stroopwafel) 팬 여러분 👋2020년에도 루비, 엘릭서, 자바스크립트 관련 글을 더 많이 발행할 계획인 저희 AppSignal은, 그 전에 2019년 한 해 동안 독자 여러분께 가장 큰 사랑을 받았던 게시물들을 돌아보려 합니다. 트위터에서 하트를 가장 많이 받고, 블로그 조회수가 가장 높았으며, 가장 많은 호평을 얻었던 글들을 한자리에 모아봤습니다.1. 자바스크립트 에러: 예외적인 역사 ✨자바스크립트의 탄생부터 격동의 성장기를 거쳐 오늘날의 언어가 되기까지, 그 흥미로운 역사를 함께 살펴봅니다.2
이번 글에서는 Ruby on Rails 애플리케이션에서 기본 스키마 형식인 schema.rb 대신 structure.sql을 사용할 때의 중요한 차이점과 장점을 살펴봅니다. 데이터가 비즈니스의 핵심이 되는 시대에 데이터베이스가 제공하는 다양한 기능을 얼마나 잘 활용하느냐가 프로젝트의 성패를 가르는 요소가 되기도 합니다.두 형식의 주요 차이점을 짚어본 뒤, structure.sql로 전환하는 방법을 알아보고, 이것이 어떻게 데이터 무결성을 보장하고 그렇지 않으면 유지할 수 없었던 데이터베이스 기능까지 보존할 수 있는지 살펴보겠습니다.