StringIO — 문자열을 감싸는 IO 디바이스

StringIO — 문자열을 감싸는 IO 디바이스

문자열을 마치 파일이나 터미널처럼 입출력 대상으로 다뤄야 할 때가 있어요. StringIO는 그런 경우에 쓸 수 있는, 문자열을 감싸는 IO 디바이스 프로세스를 제공해요.

출처: StringIO — Controls an IO device process that wraps a string

본문

StringIO로 만든 IO 디바이스는 IO 모듈에 있는 대부분의 함수에 "device"로 넘겨줄 수 있어요. 즉 파일 대신 문자열에 읽고 쓰는 것처럼 동작하게 만들 수 있다는 뜻이에요. 테스트 코드에서 표준 출력을 잡아서 검증하거나, 어떤 문자열을 입력값처럼 흘려보내고 싶을 때 아주 유용하게 쓰여요.

StringIO.open/1으로 열면 프로세스의 PID가 돌아오고, 이 PID를 IO.read/2 같은 함수에 device로 넘겨서 문자열을 읽어요.

iex> {:ok, pid} = StringIO.open("foo")
iex> IO.read(pid, 2)
"fo"

위 예시에서는 StringIO.open("foo")로 문자열 "foo"를 감싼 디바이스를 열고, IO.read(pid, 2)로 2바이트(여기서는 문자 2개)를 읽었어요.

StringIO.open/2는 두 번째 인자로 옵션을 받을 수도 있어요. 기본적으로 내부 버퍼가 비어 있는 상태로 시작하지만, input: 옵션으로 초기 입력 문자열을 넣을 수 있고, 출력이 축적되는 방식도 옵션으로 조절할 수 있어요. 예를 들어 StringIO.open("", capture_prompt: true)처럼 프롬프트 캡처를 켜서 프롬프트 출력까지 함께 얻을 수 있어요. 이렇게 만든 디바이스에서 출력을 읽어 올 때는 StringIO.contents/1을 이용해요.

iex> {:ok, pid} = StringIO.open("")
iex> IO.puts(pid, "hello")
:ok
iex> StringIO.contents(pid)
{:ok, {"", "hello\n"}}

StringIO.contents/1{:ok, {input, output}} 형태의 튜플을 돌려주는데, 첫 원소가 남아 있는 입력, 두 번째 원소가 지금까지 쌓인 출력이에요.

더 알아보기

  • 열기: StringIO.open/1, StringIO.open/2
  • 상태 읽기: StringIO.contents/1
  • 입력·출력: IO.read/2, IO.puts/2, IO.write/2 (IO 모듈)
  • 관련 개념: IO 디바이스, :stdio, 파일 디바이스