name_bank 0.2.0 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 8bdb30000d395f629f88e6a14d346c067b39049295d999c13556ca36145b1923
4
- data.tar.gz: a23fc5f83c129d4a1016be83766d4a3e4e496c634254d58ff3b2e8a1df2effd8
3
+ metadata.gz: 6e238aa5013b3c3a8513f0bd233bb7365f7703c6f852270d93044ee424f6df95
4
+ data.tar.gz: 697fe182bc1222111617ca9dd2803d208cff375aff171b41d42bf32047cef45c
5
5
  SHA512:
6
- metadata.gz: c93d2d4749bde09cbb3717118e827370acb2f6dcf7227d388e5a84b75273122606b9887b962c1908778f505cac3630a13f40c8054bb02c7837051813c6366020
7
- data.tar.gz: 1d176535f0208a680571a2f0156e80425e2adfbe6458ac26f956f06b53d25af41bf328f1bd5eb6b1d7e4d22ff8a58395fba4ba1a3ce09842480226780942183e
6
+ metadata.gz: 12411b5e09c5e83bcecefc555c7568843832ed4a37c42553d5fc8efef2c1f4699f828731b1ac68c7e5cd1db93fdbc2baf8be34207553f67bb901b9e2fbc05c6f
7
+ data.tar.gz: f959d2ec630d8d53cf461c22dfa261935e8369e866d95ce513d5e64c86b42082c0c5622ce129d4e41bce9d42a87a7182c82202baa8c842b34b478e34b61ad2ab
data/CHANGELOG.md CHANGED
@@ -4,6 +4,62 @@ All notable changes to this project are documented here. The format is based on
4
4
  [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project
5
5
  adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
6
6
 
7
+ ## [0.4.0] - 2026-08-16
8
+
9
+ Many names in one call. Nothing that worked before changes: sampling from the
10
+ existing methods is byte-identical to 0.3.0 over 2830 samples across every
11
+ country, script and variant, and the name data is untouched.
12
+
13
+ ### Added
14
+ - `full_names(country:, gender:, rng:, count:)` draws that many distinct
15
+ given/family pairs in one call — the shape a database seed needs. No pair
16
+ repeats; single names do, because only the pair is unique. The guarantee
17
+ holds within one call, so no state is kept between calls and sampling stays
18
+ a function of the caller's RNG. `count:` is required, and asking for more
19
+ pairs than the two pools can form raises the new `NameBank::PoolExhausted`
20
+ rather than silently returning fewer.
21
+
22
+ ### Fixed
23
+ - README: the first usage example showed a name pair that the seed above it
24
+ never produces. Every `# =>` in the README is now the value the code actually
25
+ returns, checked against the shipped pools. The sampling examples under
26
+ *Scripts* and *Variants* name their seed too, so all of them can be
27
+ reproduced rather than taken on trust. No code or data changed.
28
+
29
+ ## [0.3.0] - 2026-08-11
30
+
31
+ Lookup, documentation and one platform bug. Sampling behaviour and the name
32
+ data are unchanged — verified byte-identical over 1415 samples against 0.2.0.
33
+ Nothing that worked before stops working; on Linux, one thing that failed now
34
+ works.
35
+
36
+ ### Added
37
+ - `scripts` takes an optional `variant:`. A variant can offer different script
38
+ forms from the country it is layered on; previously `scripts(country:)` only
39
+ ever reported the country's own.
40
+
41
+ ### Fixed
42
+ - Country and variant names now resolve against the directory listing instead
43
+ of being handed to `File.exist?`, so lookup no longer inherits the
44
+ filesystem's case-sensitivity. `country: "de"` found `DE.yml` on macOS and
45
+ raised `UnknownCountry` on Linux; it now finds it on both. An exact match
46
+ still wins, and names that differ only in case are reported as ambiguous
47
+ rather than guessed at.
48
+ - README: a pool with no names was documented as raising
49
+ `NameBank::UnknownScript`. It has raised `NameBank::EmptyPool` since 0.2.0.
50
+
51
+ ### Documented
52
+ - The pool file format: the directory layout `NameBank.new(data_dir:)` expects,
53
+ which keys a file must carry, how `_native` pools are named, and which
54
+ failures a malformed file produces. Variant files may carry `_native` pools —
55
+ supported by the reader since 0.1.4, now stated and covered by a spec.
56
+ - `NameBank::PoolSchema` is now documented in the README and is supported
57
+ public API: `KEYS`, `GIVEN_MALE`, `GIVEN_FEMALE`, `SURNAMES`, `native_key`
58
+ and `gender_key`. It shipped before but was described nowhere. Callers
59
+ building pool files for `NameBank.new(data_dir:)` should address the YAML
60
+ keys through it. The key names are covered by semantic versioning from here
61
+ on: renaming one is a breaking change.
62
+
7
63
  ## [0.2.0] - 2026-08-08
8
64
 
9
65
  An interface release. Sampling behaviour and the name data are unchanged — the
data/README.md CHANGED
@@ -27,23 +27,23 @@ gem install name_bank
27
27
  ```ruby
28
28
  require "name_bank"
29
29
 
30
- rng = Random.new(1234)
30
+ rng = Random.new(10246)
31
31
 
32
32
  # A full name (given + family) for a country and gender:
33
33
  NameBank.full_name(country: "DE", gender: :female, rng: rng)
34
- # => { firstname: "Sabine", lastname: "Müller" }
34
+ # => { firstname: "Alexandra", lastname: "Werner" }
35
35
 
36
36
  # Just a given name or a surname:
37
- NameBank.first_name(country: "IT", gender: :male, rng: rng) # => "Amor"
38
- NameBank.last_name(country: "JP", rng: rng) # => "Tsuru"
37
+ NameBank.first_name(country: "IT", gender: :male, rng: rng) # => "Settimio"
38
+ NameBank.last_name(country: "JP", rng: rng) # => "Katsuta"
39
39
 
40
40
  # Latin (default), or the country's native script where it has one:
41
- NameBank.first_name(country: "JP", gender: :female, rng: rng) # => "Sasahara"
42
- NameBank.first_name(country: "JP", gender: :female, rng: rng, script: :native) # => "ちゃこ"
41
+ NameBank.first_name(country: "JP", gender: :female, rng: rng) # => "Misako"
42
+ NameBank.first_name(country: "JP", gender: :female, rng: rng, script: :native) # => "さえ"
43
43
 
44
44
  # Default pool, or an alternate cultural pool where one exists:
45
- NameBank.first_name(country: "US", gender: :male, rng: rng) # => "Abe"
46
- NameBank.first_name(country: "US", gender: :male, rng: rng, variant: "african_american") # => "Roosevelt"
45
+ NameBank.first_name(country: "US", gender: :male, rng: rng) # => "Jonah"
46
+ NameBank.first_name(country: "US", gender: :male, rng: rng, variant: "african_american") # => "Tyrone"
47
47
 
48
48
  # List available countries (ISO alpha-2 codes):
49
49
  NameBank.countries.size # => 106
@@ -54,10 +54,38 @@ Sampling is uniform over each pool and fully deterministic for a given
54
54
  `rng` — the same seed always yields the same name. `gender:` is `:male`
55
55
  or `:female`.
56
56
 
57
+ ## Many at once
58
+
59
+ Seeding a table wants many names in one call, and wants them to differ.
60
+ `full_names` draws distinct given/family pairs:
61
+
62
+ ```ruby
63
+ rng = Random.new(24134)
64
+
65
+ NameBank.full_names(country: "DE", gender: :female, rng: rng, count: 3)
66
+ # => [{ firstname: "Gerlinde", lastname: "Nowak" },
67
+ # { firstname: "Juliane", lastname: "Stark" },
68
+ # { firstname: "Kornelia", lastname: "Lenz" }]
69
+ ```
70
+
71
+ No pair is drawn twice. Single names do recur once the draw is large enough —
72
+ only the pair is unique, which is what a real population looks like. The
73
+ guarantee holds within one call; two calls know nothing of each other.
74
+
75
+ `count:` is required, because there is no pool of pairs to hand back without
76
+ one. A country can form as many pairs as given names × surnames: 1500 × 1500
77
+ for most, 30 × 30 for the hand-curated `CN` and `UA` pools. Asking for more
78
+ raises rather than quietly returning fewer:
79
+
80
+ ```ruby
81
+ NameBank.full_names(country: "UA", gender: :male, rng: rng, count: 901)
82
+ # => NameBank::PoolExhausted: UA: 901 pairs requested, 900 available
83
+ ```
84
+
57
85
  ## Whole pools
58
86
 
59
- Where sampling one name is not enough — drawing many names without repeats,
60
- applying your own weighting, or checking what a country actually ships —
87
+ Where sampling is not enough — applying your own weighting, drawing single
88
+ names without repeats, or checking what a country actually ships —
61
89
  take the pool itself. `first_names` and `last_names` accept the same
62
90
  `country:`, `variant:` and `script:` options as the samplers, and return the
63
91
  frequency-ordered pool as a frozen array:
@@ -68,6 +96,11 @@ NameBank.first_names(country: "DE", gender: :female).first(3) # => ["Nicole", "
68
96
  NameBank.last_names(country: "JP", script: :native).first(3) # => ["佐藤", "鈴木", "田中"]
69
97
  ```
70
98
 
99
+ For single names without repeats, the pool plus Ruby is the whole answer:
100
+ `pool.sample(200, random: rng)` returns 200 different names, deterministically.
101
+ Note that `Array#sample` returns fewer than asked for rather than complaining
102
+ when the pool is too small — unlike `full_names`, which raises.
103
+
71
104
  Every method shown so far is also available on an instance, which lets you
72
105
  point name_bank at your own directory of pool files:
73
106
  `NameBank.new(data_dir: "…").first_name(country: "DE", gender: :male, rng: rng)`.
@@ -153,6 +186,8 @@ Names come in Latin (default) and, for countries with a non-Latin writing
153
186
  system, their native script. Pass `script:`:
154
187
 
155
188
  ```ruby
189
+ rng = Random.new(325089)
190
+
156
191
  NameBank.first_name(country: "RU", gender: :male, rng: rng) # => "Dmitry"
157
192
  NameBank.first_name(country: "RU", gender: :male, rng: rng, script: :native) # => "Алексей"
158
193
 
@@ -163,7 +198,15 @@ NameBank.scripts(country: "DE") # => [:latin]
163
198
  Germany's script is Latin, so `DE` reports `:latin` only.
164
199
  `:latin` and `:native` sample from independent pools. For Latin-script countries
165
200
  `:native` returns the same (Latin) pool. Requesting a script with no names
166
- raises `NameBank::UnknownScript`.
201
+ raises `NameBank::EmptyPool`; a `script:` that is neither `:latin` nor
202
+ `:native` raises `NameBank::UnknownScript`.
203
+
204
+ `scripts` takes an optional `variant:`, because a variant can offer different
205
+ forms from the country it is layered on:
206
+
207
+ ```ruby
208
+ NameBank.scripts(country: "US", variant: "african_american") # => [:latin]
209
+ ```
167
210
 
168
211
  ## Variants
169
212
 
@@ -171,6 +214,8 @@ Some countries offer an alternate cultural name pool layered on the default.
171
214
  Pass `variant:`:
172
215
 
173
216
  ```ruby
217
+ rng = Random.new(41)
218
+
174
219
  NameBank.first_name(country: "US", gender: :male, rng: rng, variant: "african_american")
175
220
  # => "DeShawn"
176
221
 
@@ -191,10 +236,11 @@ still catches the two that are genuinely caller mistakes:
191
236
  | `NameBank::UnknownCountry` | `StandardError` | no pool file for that country code |
192
237
  | `NameBank::UnknownVariant` | `StandardError` | no pool file for that variant |
193
238
  | `NameBank::EmptyPool` | `StandardError` | the pool exists but holds no names |
239
+ | `NameBank::PoolExhausted` | `StandardError` | `full_names` was asked for more distinct pairs than the pools can form |
194
240
  | `NameBank::MalformedPool` | `StandardError` | a pool file is missing a key, or holds something other than a list |
195
241
 
196
- The last two cannot occur with the shipped data; they matter when you point
197
- `NameBank.new(data_dir:)` at pool files of your own.
242
+ `EmptyPool` and `MalformedPool` cannot occur with the shipped data; they matter
243
+ when you point `NameBank.new(data_dir:)` at pool files of your own.
198
244
 
199
245
  ```ruby
200
246
  begin
@@ -204,6 +250,94 @@ rescue NameBank::UnknownCountry => e
204
250
  end
205
251
  ```
206
252
 
253
+ ## Pool file format
254
+
255
+ `NameBank.new(data_dir:)` reads pools from a directory of your own. It holds
256
+ two subdirectories:
257
+
258
+ ```
259
+ my_names/
260
+ countries/
261
+ DE.yml
262
+ RU.yml
263
+ variants/
264
+ US/
265
+ african_american.yml
266
+ ```
267
+
268
+ - `countries/<code>.yml` — the basename is what you pass as `country:`, and
269
+ what `countries` lists.
270
+ - `variants/<code>/<name>.yml` — the basename is what you pass as `variant:`.
271
+ No directory for a country means `variants(country:)` returns `[]`.
272
+ - Files that do not end in `.yml` are ignored, and codes are not validated
273
+ against ISO 3166 — any basename works.
274
+
275
+ Names resolve the same way on every filesystem: an exact match wins, otherwise
276
+ a unique match ignoring case, so `country: "de"` finds `DE.yml` on Linux as
277
+ well as macOS. Two files whose basenames differ only in case are ambiguous, and
278
+ raise `NameBank::UnknownCountry` rather than being guessed at.
279
+
280
+ A pool file must carry the three keys in `NameBank::PoolSchema::KEYS`, each a
281
+ list. Any of them may have a native-script counterpart under the same key plus
282
+ `_native`:
283
+
284
+ ```yaml
285
+ firstnames_male: [Dmitry, Ivan]
286
+ firstnames_female: [Anna, Olga]
287
+ lastnames: [Ivanov, Petrov]
288
+
289
+ firstnames_male_native: [Дмитрий, Иван]
290
+ lastnames_native: [Иванов, Петров]
291
+ ```
292
+
293
+ Variant files are validated the same way and need all three keys too. They may
294
+ carry `_native` pools, which `script: :native` will use — the shipped variants
295
+ do not, because the build pipeline strips them.
296
+
297
+ Missing a required key, or holding something other than a list under it, raises
298
+ `NameBank::MalformedPool` when the file is read. A key that is present but
299
+ empty is accepted at read time and raises `NameBank::EmptyPool` when sampled.
300
+ Any other key is ignored; the shipped files carry `source:`, which nothing
301
+ reads at runtime.
302
+
303
+ Sampling is uniform over the whole list, so order does not weight anything. It
304
+ is preserved, and visible through `first_names` and `last_names`.
305
+
306
+ ## Pool schema
307
+
308
+ `NameBank::PoolSchema` names the YAML keys a pool file uses. It is supported
309
+ public API from 0.2.0 on: the constants and their values will not change
310
+ without a version bump. Use it when you build pool files for
311
+ `NameBank.new(data_dir:)`, so you are not typing key names by hand.
312
+
313
+ ```ruby
314
+ NameBank::PoolSchema::KEYS
315
+ # => ["firstnames_male", "firstnames_female", "lastnames"]
316
+
317
+ NameBank::PoolSchema::GIVEN_MALE # => "firstnames_male"
318
+ NameBank::PoolSchema::GIVEN_FEMALE # => "firstnames_female"
319
+ NameBank::PoolSchema::SURNAMES # => "lastnames"
320
+ ```
321
+
322
+ `KEYS` is frozen and lists the three pools every file must carry. A file may
323
+ also carry a native-script pool for any of them, under the same key with a
324
+ `_native` suffix:
325
+
326
+ ```ruby
327
+ NameBank::PoolSchema.native_key("lastnames") # => "lastnames_native"
328
+ ```
329
+
330
+ `gender_key` maps a `gender:` argument to its key, and raises
331
+ `NameBank::UnknownGender` for anything else:
332
+
333
+ ```ruby
334
+ NameBank::PoolSchema.gender_key(:female) # => "firstnames_female"
335
+ NameBank::PoolSchema.gender_key(:x) # raises NameBank::UnknownGender
336
+ ```
337
+
338
+ Reading a file that is missing one of `KEYS`, or that holds something other
339
+ than a list under it, raises `NameBank::MalformedPool`.
340
+
207
341
  ## Supported countries
208
342
 
209
343
  106 countries: Afghanistan, Albania, Algeria, Angola, Argentina, Austria,
@@ -28,6 +28,11 @@ class NameBank
28
28
  include Error
29
29
  end
30
30
 
31
+ # More distinct pairs were asked for than the pools can form.
32
+ class PoolExhausted < StandardError
33
+ include Error
34
+ end
35
+
31
36
  # script: was neither :latin nor :native.
32
37
  class UnknownScript < ArgumentError
33
38
  include Error
@@ -5,8 +5,13 @@ require_relative "errors"
5
5
  # Declared as a class, not a module: NameBank itself is one (see lib/name_bank.rb).
6
6
  class NameBank
7
7
  # The pool-key schema: the base YAML keys, how native-script keys are named,
8
- # and how a gender maps to its key. Shared by the runtime NameBank and the
9
- # build-time SplitScripts tool so the key names live in one place.
8
+ # and how a gender maps to its key. One home for the key names, shared by the
9
+ # runtime NameBank and the build-time SplitScripts tool.
10
+ #
11
+ # Supported public API from 0.2.0 on, documented in the README — callers
12
+ # building pool files for NameBank.new(data_dir:) address them through here.
13
+ # The constants and their values are therefore covered by semantic
14
+ # versioning: changing a key name is a breaking change.
10
15
  module PoolSchema
11
16
  GIVEN_MALE = "firstnames_male"
12
17
  GIVEN_FEMALE = "firstnames_female"
@@ -11,6 +11,10 @@ class NameBank
11
11
  # shape against PoolSchema, memoizing them, and listing what a data dir holds.
12
12
  # NameBank itself never opens a file. Files are read once per instance, and
13
13
  # validated once when read rather than on every pool access.
14
+ #
15
+ # Country and variant names are resolved against the directory listing rather
16
+ # than handed to File.exist?, so the result does not depend on whether the
17
+ # filesystem happens to be case-sensitive.
14
18
  class PoolStore
15
19
  def initialize(data_dir)
16
20
  @data_dir = data_dir
@@ -28,27 +32,49 @@ class NameBank
28
32
  end
29
33
 
30
34
  def variants(country)
31
- @variant_names[country] ||= yml_basenames(File.join(@data_dir, "variants", country))
35
+ code = resolve(country, variant_countries)
36
+ return [] if code.nil?
37
+
38
+ @variant_names[code] ||= yml_basenames(File.join(@data_dir, "variants", code))
32
39
  end
33
40
 
34
41
  private
35
42
 
43
+ # An exact match wins; otherwise a unique case-insensitive one; otherwise
44
+ # nil, because guessing between DE and de would be worse than refusing.
45
+ def resolve(name, candidates)
46
+ return name if candidates.include?(name)
47
+
48
+ hits = matches(name, candidates)
49
+ hits.size == 1 ? hits.first : nil
50
+ end
51
+
52
+ def matches(name, candidates)
53
+ candidates.select { |candidate| candidate.casecmp?(name) }
54
+ end
55
+
56
+ # What to put in the error: the name alone when nothing matched, or the
57
+ # rival spellings when several did.
58
+ def unresolved(name, candidates)
59
+ hits = matches(name, candidates)
60
+ hits.empty? ? name : "#{name} matches #{hits.join(", ")}"
61
+ end
62
+
36
63
  def country_pools(country)
37
- @country_pools[country] ||= begin
38
- path = File.join(@data_dir, "countries", "#{country}.yml")
39
- raise UnknownCountry, country unless File.exist?(path)
64
+ code = resolve(country, countries)
65
+ raise UnknownCountry, unresolved(country, countries) if code.nil?
40
66
 
41
- read(path)
42
- end
67
+ @country_pools[code] ||= read(File.join(@data_dir, "countries", "#{code}.yml"))
43
68
  end
44
69
 
45
70
  def variant_pools(country, variant)
46
- @variant_pools[[country, variant]] ||= begin
47
- path = File.join(@data_dir, "variants", country, "#{variant}.yml")
48
- raise UnknownVariant, "#{country}/#{variant}" unless File.exist?(path)
71
+ code = resolve(country, variant_countries)
72
+ raise UnknownVariant, "#{country}/#{variant}" if code.nil?
49
73
 
50
- read(path)
51
- end
74
+ name = resolve(variant, variants(code))
75
+ raise UnknownVariant, "#{country}/#{unresolved(variant, variants(code))}" if name.nil?
76
+
77
+ @variant_pools[[code, name]] ||= read(File.join(@data_dir, "variants", code, "#{name}.yml"))
52
78
  end
53
79
 
54
80
  def read(path)
@@ -59,6 +85,16 @@ class NameBank
59
85
  data
60
86
  end
61
87
 
88
+ def variant_countries
89
+ @variant_countries ||= subdirectories(File.join(@data_dir, "variants"))
90
+ end
91
+
92
+ def subdirectories(dir)
93
+ return [] unless Dir.exist?(dir)
94
+
95
+ Dir.children(dir).select { |child| File.directory?(File.join(dir, child)) }.sort
96
+ end
97
+
62
98
  def yml_basenames(dir)
63
99
  return [] unless Dir.exist?(dir)
64
100
 
@@ -2,5 +2,5 @@
2
2
 
3
3
  # Declared as a class, not a module: NameBank itself is one (see lib/name_bank.rb).
4
4
  class NameBank
5
- VERSION = "0.2.0"
5
+ VERSION = "0.4.0"
6
6
  end
data/lib/name_bank.rb CHANGED
@@ -27,6 +27,7 @@ class NameBank
27
27
  def first_name(...) = default.first_name(...)
28
28
  def last_name(...) = default.last_name(...)
29
29
  def full_name(...) = default.full_name(...)
30
+ def full_names(...) = default.full_names(...)
30
31
  def first_names(...) = default.first_names(...)
31
32
  def last_names(...) = default.last_names(...)
32
33
  def countries(...) = default.countries(...)
@@ -53,6 +54,21 @@ class NameBank
53
54
  }
54
55
  end
55
56
 
57
+ # Distinct given/family pairs, for seeding many rows at once. No pair is drawn
58
+ # twice; single names do recur, which is what a population looks like. The
59
+ # guarantee holds within one call — two calls know nothing of each other.
60
+ # Asking for more pairs than the two pools can form raises PoolExhausted.
61
+ def full_names(country:, gender:, rng:, count:, variant: nil, script: :latin)
62
+ firsts = first_names(country: country, gender: gender, variant: variant, script: script)
63
+ lasts = last_names(country: country, variant: variant, script: script)
64
+ available = firsts.size * lasts.size
65
+ raise PoolExhausted, "#{country}: #{count} pairs requested, #{available} available" if count > available
66
+
67
+ distinct_indices(available, count, rng).map do |index|
68
+ { firstname: firsts[index / lasts.size], lastname: lasts[index % lasts.size] }
69
+ end
70
+ end
71
+
56
72
  # The whole frequency-ordered pool, frozen. The name strings stay mutable.
57
73
  def first_names(country:, gender:, variant: nil, script: :latin)
58
74
  pool(country, variant, PoolSchema.gender_key(gender), script)
@@ -71,13 +87,28 @@ class NameBank
71
87
  end
72
88
 
73
89
  # The script forms this country offers, not writing systems — see CONTEXT.md.
74
- def scripts(country:)
75
- data = @store.pools(country, nil)
90
+ # With a variant, the forms that variant offers, which may differ.
91
+ def scripts(country:, variant: nil)
92
+ data = @store.pools(country, variant)
76
93
  PoolSchema::KEYS.any? { |k| data[PoolSchema.native_key(k)]&.any? } ? %i[latin native] : %i[latin]
77
94
  end
78
95
 
79
96
  private
80
97
 
98
+ # Partial Fisher-Yates over the space of pair indices, with the swaps kept in
99
+ # a Hash so that the untouched majority of a two-million-pair space is never
100
+ # built. Drawing every pair a country has takes count steps; drawing at random
101
+ # until enough distinct pairs turn up would stall on the last few.
102
+ def distinct_indices(available, count, rng)
103
+ swapped = {}
104
+ Array.new(count) do |drawn|
105
+ index = rng.rand(drawn...available)
106
+ picked = swapped.fetch(index, index)
107
+ swapped[index] = swapped.fetch(drawn, drawn)
108
+ picked
109
+ end
110
+ end
111
+
81
112
  def pool(country, variant, key, script)
82
113
  names = names_for_script(@store.pools(country, variant), key, script)
83
114
  raise EmptyPool, "#{country}/#{script}" if names.empty?
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: name_bank
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Patrick Bartels