본문으로 건너뛰기

시작하기

randino는 하나의 데이터셋을 세 개의 패키지로 제공합니다. 사이드바에서 사용할 언어를 고르세요. 이 사이트의 모든 코드 예제는 그 선택을 따라갑니다.

JavaScript 패키지는 npm에 randino로 배포됩니다. 타입 선언이 포함된 ESM이며 런타임 의존성이 없습니다. 뒤따라 설치되는 패키지가 없고, Node와 브라우저 양쪽에서 그대로 동작합니다.

Dart 패키지는 pub.dev에 randino로 배포됩니다. 순수 Dart로 작성되어 dart:math 외에는 아무것도 import하지 않으므로, VM과 웹은 물론 모든 플랫폼의 Flutter에서 플러그인이나 에셋 없이 동작합니다.

Python 패키지는 PyPI에 randino로 배포됩니다. 순수 Python으로 작성되어 표준 라이브러리 외에는 아무것도 import하지 않으며, py.typed 마커를 포함하므로 mypy와 Pyright가 타입 주석을 무시하지 않고 그대로 읽습니다.

세 패키지의 출력은 동일합니다. 이름 풀, 가중치, 길이 규칙, 로마자 표기는 하나의 구현을 세 언어로 옮긴 것이고, 세 테스트 스위트가 같은 데이터에 대해 같은 속성을 검증합니다. 다만 버전은 각각 관리하므로 npm, pub.dev, PyPI의 버전 번호는 항상 같지는 않습니다.

설치

bash
npm install randino

Node.js 22 이상 또는 아무 브라우저면 됩니다. 설치는 이게 전부이고, 따로 설정할 것이 없습니다.

bash
dart pub add randino

Dart 3.7 이상(Flutter 3.29)이면 됩니다. 설치는 이게 전부이고, 따로 설정할 것이 없습니다.

bash
pip install randino

Python 3.10 이상이면 됩니다. 설치는 이게 전부이고, 따로 설정할 것이 없습니다.

브라우저 번들에서 차지하는 용량

이 패키지는 sideEffects: false를 선언하므로, 번들러가 아무도 쓰지 않는 단어 풀을 덜어냅니다. 그리고 이 라이브러리는 거의 전부가 단어 풀입니다. 함수 하나를 가져올 때의 용량은 다음과 같습니다(minify + gzip 기준).

가져오는 함수gzip
randSuffix, randPrefix0.5 KB
randName23 KB
randWord와 테마별 함수들, randModifier265 KB
randNickname267 KB
randSentence449 KB

단어 풀은 언어마다 객체 하나이므로 테마 하나만 써도 29개 전부와 같은 용량이 들고, randSentence는 그 위에 문법 데이터가 더해집니다. 의존성 없는 동기 API가 치르는 대가입니다. 아무것도 내려받지 않는 대신, 함수가 닿을 수 있는 모든 것이 함께 실립니다. 서버에서는 신경 쓸 일이 아니지만, 브라우저 번들이라면 randName이나 데코레이터만으로 충분한지 먼저 보고, randSentence는 별도 청크로 불러오는 편이 낫습니다.

첫 번째 이름

javascript
import { randName } from 'randino';

randName();
// ['Emma Clover']
dart
import 'package:randino/randino.dart';

randName();
// ['Emma Clover']
python
from randino import rand_name

rand_name()
# ['Emma Clover']

모든 옵션에 기본값이 있어서 인자 없이 호출해도 동작하며, 지원하는 9개 언어 중 하나로 된 이름 하나가 돌아옵니다. 기본값은 여러 언어를 섞는 것입니다. 샘플 데이터에는 알맞지만 한 언어로 통일해야 하는 화면에는 맞지 않으니, 그럴 때는 언어를 지정하면 됩니다.

javascript
randName({ language: 'en', count: 3 });
// ['Christina Mills', 'Jack Reeves', 'Brian Wallace']
dart
randName(language: NameLanguage.en, count: 3);
// ['Christina Mills', 'Jack Reeves', 'Brian Wallace']
python
rand_name(language="en", count=3)
# ['Christina Mills', 'Jack Reeves', 'Brian Wallace']

첫 번째 닉네임

randino는 닉네임과 이름을 의도적으로 분리합니다. 닉네임은 동물, 사물, 장소, 음식 같은 일상 단어로만 만들고 사람 이름은 쓰지 않습니다. 생성된 핸들이 누군가의 실명처럼 읽히지 않는 것은 이 규칙 덕분입니다.

javascript
import { randNickname } from 'randino';

randNickname({ language: 'en', count: 3 });
// ['FoggyHillside', 'CraneVoyage', 'TinyLeopardCloak']
dart
import 'package:randino/randino.dart';

randNickname(language: WordLanguage.en, count: 3);
// ['FoggyHillside', 'CraneVoyage', 'TinyLeopardCloak']
python
from randino import rand_nickname

rand_nickname(language="en", count=3)
# ['FoggyHillside', 'CraneVoyage', 'TinyLeopardCloak']

옵션을 쓰는 방식

세 패키지는 같은 이름의 같은 옵션을 받습니다. 다른 것은 옵션을 전달하는 형태뿐입니다.

모든 함수는 옵션 객체 하나를 받고, 그 안의 모든 키는 선택 사항입니다.

javascript
randName({
	language: 'ja',
	gender: 'female',
	count: 5,
	script: 'roman'
});

"전부"를 뜻하는 값은 'all'이고, language, gender, theme의 기본값이 그것입니다.

모든 함수는 named parameter를 받고, 모든 파라미터가 선택 사항입니다.

dart
randName(
  language: NameLanguage.ja,
  gender: NameGender.female,
  count: 5,
  script: NameScript.roman,
);

"전부"를 뜻하는 것은 null인 enum, 즉 파라미터를 아예 쓰지 않는 것입니다. NameLanguage.all 같은 값은 없습니다. 쓰지 않은 파라미터가 이미 Dart에서 "지정하지 않음"을 뜻하기 때문입니다.

dart
randName(count: 5); // 9개 언어 중 하나씩, 이름 다섯 개

null이 다른 뜻을 갖는 곳은 NicknameDetail.theme 하나뿐입니다. 여기서 null은 그 단어를 생성기가 모른다는 뜻으로, 새로 만들어낸 단어인 경우입니다.

모든 함수는 키워드 전용 인자를 받고, 모든 인자가 선택 사항입니다.

python
rand_name(
    language="ja",
    gender="female",
    count=5,
    script="roman",
)

키워드 전용인 것은 의도적입니다. rand_name("ja", "female", 5)는 짧게 쓸 수는 있지만 읽을 수 없고, 파라미터 순서를 API에 고정시켜 버립니다. 그래서 위치 인자 형태는 아예 제공하지 않습니다.

옵션 값은 npm 패키지가 쓰는 것과 같은 문자열이며 Literal로 타입이 지정되어 있어서, language="kr" 같은 실수는 실행 전에 타입 검사기가 잡아냅니다. "전부"를 뜻하는 값은 "all"이고, language, gender, theme의 기본값이 그것입니다.

python
rand_name(count=5)  # 9개 언어 중 하나씩, 이름 다섯 개

이름은 snake_case를 씁니다. includeMiddleNameinclude_middle_name, minLengthmin_length, startsWithstarts_with입니다.

난수원 고르기

모든 생성 함수와 데코레이터가 random 옵션을 받고, 한 번의 호출이 하는 모든 추첨이 이 난수원을 거칩니다. 생성기가 다른 생성기를 부르며 하는 추첨도 마찬가지라서, randSentence가 쓰는 사람 이름도 문장과 같은 난수원에서 나옵니다. 생략하면 각 언어의 일반 난수 생성기를 씁니다. Math.random, dart:mathRandom, Python의 random입니다.

샘플 데이터에는 이 기본값으로 충분하지만, 두 가지 경우에는 맞지 않습니다.

아무도 예측하면 안 되는 값. 위 생성기들은 모두 암호학적으로 안전하지 않습니다. 작은 내부 상태를 굴리는 방식이라 출력 몇 개로 상태가 복원됩니다. 추측 불가능해야 하는 토큰에는 보안 난수원을 넘기십시오.

javascript
const secure = () => crypto.getRandomValues(new Uint32Array(1))[0] / 2 ** 32;

randSuffix('MistyOwl', { random: secure }); // 'MistyOwl_k3Rm9'
dart
import 'dart:math';

randSuffix(value: 'MistyOwl', random: Random.secure()); // 'MistyOwl_k3Rm9'
python
from random import SystemRandom

rand_suffix("MistyOwl", random=SystemRandom().random)  # 'MistyOwl_k3Rm9'

매번 같아야 하는 고정 데이터. 시드를 준 난수원을 넘기면 호출 전체가 재현됩니다. 스냅샷 테스트나 데모용 데이터베이스에 쓰기 좋습니다. 시드와 옵션이 같으면 결과도 같습니다.

javascript
// 시드를 받는 생성기는 표준 라이브러리에 없으니 직접 준비합니다.
const seeded = (seed) => () => /* … */;

randName({ language: 'en', count: 3, random: seeded(42) });
// ['Easton Bryant', 'Pearl Fenwick', 'Callum Bradley'] — 언제나 같습니다
dart
randName(language: NameLanguage.en, count: 3, random: Random(42));
// ['Quinn Palmer', 'Bryson Compton', 'Hannah Evans'] — 언제나 같습니다
python
from random import Random

rand_name(language="en", count=3, random=Random(42).random)
# ['Simon Bancroft', 'Liam Norton', 'Jordan Sutton'] — 언제나 같습니다

시드를 준 결과는 같은 버전 안에서만 재현됩니다. 단어 풀은 계속 늘어나고, 단어 하나가 추가되면 그 뒤의 모든 추첨이 밀립니다. 고정 데이터가 업그레이드를 넘어 살아남아야 한다면 버전을 고정하십시오.

다음으로

  • 지원 언어 — 9개 언어 코드가 무엇을 다루는지, 그리고 언어마다 무엇이 다른지.
  • 사람 이름 — 모든 옵션과 각 옵션이 출력에 미치는 영향.
  • 닉네임 — 모든 옵션과 형태를 고르는 방식.
  • randWord — 29개 테마의 단어와 테마마다 하나씩 있는 함수.
  • randSentence — 그 언어의 문법으로 쓴 완결된 문장.
  • randModifier — 어떤 문자열 앞에든 수식어를 붙이는 함수.

Released under the MIT License