unique_names_generator 0.1.1 → 0.2.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: 9c3735cb47c574108e11dde60274f4d2013c0b281fd2bdf08cecc595e9acd2ac
4
- data.tar.gz: 9ccbf1f0f972547de8baabe8675b1a1540ace3a4a24caf3dd88728d86650ba52
3
+ metadata.gz: f9773f651a33cab35886353896b6138a9e1df7d1bbecf1c0573be4da2567eda2
4
+ data.tar.gz: 3dac60147e276911a7c17c505afe95e305800e6aeb897797d925a1844fe2d57d
5
5
  SHA512:
6
- metadata.gz: c049f7832bc38164a17215c3ddaf830b534ec642b25494045f89c39ccb08d7c639a39af7fd061e988173bc7c5190eb8a634f2ebaed562b286d80411cbe77cdb9
7
- data.tar.gz: f9a0be92fb3dbbe8a48bc588b202217d97edcd299f21699a26d7712d9b5129cb8dd0a535ffb7c4f0976bc0377f983f4e047fb9a597800131157262efc623de92
6
+ metadata.gz: 61b362f06916f9f08ab89e91421a4ee0c482433a4d6c9843645d6b02feab966d6197383993425fbf8b1740d211ea53ef149e9d632df0669172755a57be977a32
7
+ data.tar.gz: 0534cb36f75cc5e04fe72c9cdae7e05199880d0e06f1b3e0d7f6f797644f882980356232a79a2c06bb0a54da29ffbdc67f07e22ee6b2e96b9d51548e0aae78e5
data/.gitignore ADDED
@@ -0,0 +1,3 @@
1
+ *.gem
2
+ .DS_Store
3
+ .yardoc
data/.rubocop.yml CHANGED
@@ -27,5 +27,12 @@ Style/SymbolArray:
27
27
  Exclude:
28
28
  - 'spec/**/*'
29
29
 
30
+ Layout/SpaceInsideBlockBraces:
31
+ Exclude:
32
+ - 'spec/**/*'
33
+
30
34
  Style/NumericPredicate:
31
- Enabled: false
35
+ Enabled: false
36
+
37
+ Metrics/ClassLength:
38
+ Max: 150
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- unique_names_generator (0.1.0)
4
+ unique_names_generator (0.2.0)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
data/README.md CHANGED
@@ -12,7 +12,7 @@ by adding `unique_names_generator` to your list of gemfile dependencies:
12
12
  Add this line to your application's Gemfile:
13
13
 
14
14
  ```
15
- gem 'unique_names_generator', "~> 0.1.0"
15
+ gem 'unique_names_generator', '~> 0.2.0'
16
16
  ```
17
17
 
18
18
  And then execute:
@@ -29,16 +29,19 @@ $ gem install unique_names_generator
29
29
 
30
30
  ## Usage
31
31
 
32
- In a nutshell, you can begin generating randon names with UniqueNamesGenerator by simply specifying an array of one or more dictionaries via `UniqueNamesGenerator.generate`. Available dictionary types are `[:adjectives, :animals, :colors, :languages, :names, :numbers, :star_wars]`.
32
+ In a nutshell, you can begin generating random names with UniqueNamesGenerator by simply creating a Generator instance and specifying an array of one or more dictionaries. Available dictionary types are `[:adjectives, :animals, :colors, :languages, :names, :numbers, :star_wars]`.
33
33
 
34
34
  ```ruby
35
- UniqueNamesGenerator.generate([:adjectives, :animals])
35
+ generator = UniqueNamesGenerator::Generator.new([:adjectives, :animals])
36
+ generator.generate
36
37
  # => Generates ex: "dramatic_limpet"
37
38
 
38
- UniqueNamesGenerator.generate([:adjectives, :colors, :animals])
39
+ generator = UniqueNamesGenerator::Generator.new([:adjectives, :colors, :animals])
40
+ generator.generate
39
41
  # => Generates ex: "tremendous_brown_cat"
40
42
 
41
- UniqueNamesGenerator.generate([:adjectives, :names, :numbers])
43
+ generator = UniqueNamesGenerator::Generator.new([:adjectives, :names, :numbers])
44
+ generator.generate
42
45
  # => Generates ex: "doubtful_wanda_979"
43
46
  ```
44
47
 
@@ -46,7 +49,9 @@ To use custom dictionaries, simply include your array of strings as part of the
46
49
 
47
50
  ```ruby
48
51
  drinks = ['Sprite', 'Coca-Cola', 'Juice', 'Tea']
49
- UniqueNamesGenerator.generate([:colors, drinks])
52
+
53
+ generator = UniqueNamesGenerator::Generator.new([:colors, drinks])
54
+ generator.generate
50
55
  # => Generates ex: "cyan_sprite"
51
56
  ```
52
57
 
@@ -55,17 +60,20 @@ UniqueNamesGenerator.generate([:colors, drinks])
55
60
  UniqueNamesGenerator can be used with either the default provided config (`separator: '_', style: :lowercase, creativity: 0`) or by specifying any of your own configuration options for seeding, seperator, style and creativity.
56
61
 
57
62
  #### More details on possible options
58
-
59
- - **Separator options**: Any ASCII character string such as underscore, dash or blank space. `nil` for no space.
63
+ - **Dictionaries**: [Array<Symbol, Array<String>>] List of dictionaries to use for name generation. Can be symbols referring to built-in dictionaries or custom arrays of strings.
64
+ - **Separator**: [String] Character(s) used to join words in the generated name. Default: '_'. `nil` can be used for no space.
60
65
  - ex: '_', '-', ' ' or `nil` for no space.
61
- - **Style options**: Atom, one of `:lowercase`, `:uppercase`, `:capital`.
62
- - **Creativity options**: An integer or float between 1 and 10.
66
+ - **Style**: [Symbol] Capitalization style for generated names.
67
+ - Options: `:lowercase`, `:uppercase`, `:capital`. Default: `:lowercase`
68
+ - **Creativity**: [Integer] Level of creativity in name generation, affecting word selection. Must be between 0 and 10. A Float value can also be used. Default: 0
63
69
 
64
70
  ```ruby
65
- UniqueNamesGenerator.generate([:colors, :animals], style: :capital, separator: ' ')
71
+ generator = UniqueNamesGenerator::Generator.new([:colors, :animals], style: :capital, separator: ' ')
72
+ generator.generate
66
73
  # => Generates ex: "Lavender Marlin"
67
74
 
68
- UniqueNamesGenerator.generate([:colors, :adjectives, :animals], creativity: 8, style: :capital, separator: ' ')
75
+ generator = UniqueNamesGenerator::Generator.new([:colors, :adjectives, :animals], creativity: 8, style: :capital, separator: ' ')
76
+ generator.generate
69
77
  # => Generates ex: "Yellow Local Hippopotamus"
70
78
  ```
71
79
 
@@ -73,20 +81,22 @@ UniqueNamesGenerator.generate([:colors, :adjectives, :animals], creativity: 8, s
73
81
  Using the creativity option changes how `UniqueNamesGenerator` selects terms from the dictionaries in use, essentially acting as a multiplier. For dictionaries with a similar term length, while using a seed, the selection may at times appear to be alphabetical or closely related (ex: "Amber Anakin Skywalker"). Utilizing the `creative` option with a value between 1 and 10 will use a sequential multiplier for subsequent dictionaries providing a seemingly more "random" or "creative" result whilst still allowing for seeded generation.
74
82
 
75
83
  ```ruby
76
- UniqueNamesGenerator.generate([:colors, :adjectives, :animals], creativity: 8, seed: 'f6da7a28-5ae6-4d6b-b3b8-a197b99ed4eb')
84
+ generator = UniqueNamesGenerator::Generator.new([:colors, :adjectives, :animals], creativity: 8)
85
+ generator.generate(seed: 'f6da7a28-5ae6-4d6b-b3b8-a197b99ed4eb')
77
86
 
78
87
  # => Seed "f6da7a28-5ae6-4d6b-b3b8-a197b99ed4eb" with creativity of 8 always generates: "plum_flying_cobra"
79
88
  ```
80
89
 
81
90
  ### Seeded Generation
82
91
 
83
- A seed can be used to deterministically generate a name. As long as the provided seed and creativity values are the same between runs, then the generated name will also always be the same. Simply provide a string or integer as the value of the seed key, ie; `seed: 'hello'`.
92
+ A seed can be used to deterministically generate a name. As long as the provided seed and creativity values are the same between runs, then the generated name will also always be the same. Simply provide a string or integer as an argument to the generate method, ie; `seed: 'hello'`.
84
93
 
85
- _(**Usecase example:** generate a username for an authenticated user based on UUID. Ex: `13a5d03e-61d0-4b5b-ae3b-57953c268c5f` will always generate the name "beige_boba_fett_145" when used together with the colors/star_wars/numbers dictionaries)._
94
+ _(**Usecase example:** generate a username for an authenticated user based on UUID. Ex: `13a5d03e-61d0-4b5b-ae3b-57953c268c5f` will always generate the name "coral_greedo_320" when used together with the colors/star_wars/numbers dictionaries)._
86
95
 
87
96
  ```ruby
88
- UniqueNamesGenerator.generate([:colors, :star_wars, :numbers], seed: '13a5d03e-61d0-4b5b-ae3b-57953c268c5f')
89
- # => Seed "13a5d03e-61d0-4b5b-ae3b-57953c268c5f" always generates: "beige_boba_fett_145"
97
+ generator = UniqueNamesGenerator::Generator.new([:colors, :star_wars, :numbers])
98
+ generator.generate(seed: '13a5d03e-61d0-4b5b-ae3b-57953c268c5f')
99
+ # => Seed "13a5d03e-61d0-4b5b-ae3b-57953c268c5f" always generates: "coral_greedo_320"
90
100
  ```
91
101
 
92
102
  ## License
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module UniqueNamesGenerator
4
- VERSION = '0.1.1'
4
+ VERSION = '0.2.0'
5
5
  end
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  # An implementation of a unique_names_generator in Ruby
4
- # with support for PRNG/seeds
4
+ # with support for PRNG/deterministic seeds
5
5
 
6
6
  require_relative './unique_names_generator/seed'
7
7
 
@@ -15,178 +15,170 @@ require_relative './unique_names_generator/dictionaries/star_wars'
15
15
 
16
16
  # UniqueNamesGenerator implementation
17
17
  module UniqueNamesGenerator
18
- module_function
19
-
20
- def generate(dictionaries, separator: '_', style: :lowercase, seed: nil, creativity: 0)
21
- @separator = separator
22
- @style = style
23
- @seed = seed
24
- @creativity = creativity
18
+ # UniqueNamesGenerator::Generator
19
+ #
20
+ # This class generates unique names based on specified dictionaries and configuration options.
21
+ # It allows for customizable name generation with various styles, separators, and creativity levels.
22
+ class Generator
23
+ def initialize(dictionaries, separator: '_', style: :lowercase, creativity: 0)
24
+ @dictionaries = dictionaries
25
+ @separator = separator
26
+ @style = style
27
+ @creativity = creativity
28
+
29
+ # Will raise error if any specified dictionary is invalid
30
+ dictionaries.map { |dictionary| word_list(dictionary) }
31
+ raise ArgumentError, 'Outside creativity range. Must be between 0 and 10.' if outside_creativity_bounds?
32
+ end
25
33
 
26
- if creativity.negative? || creativity > 10
27
- raise ArgumentError, 'Outside creativity range. Must be between 0 and 10.'
34
+ def generate(seed: nil)
35
+ @seed = seed
36
+ generate_name(@dictionaries)
28
37
  end
29
38
 
30
- generate_name(dictionaries)
31
- end
39
+ private
32
40
 
33
- def match_word_list(dictionary)
34
- module_name = camelize_dictionary(dictionary)
35
- begin
36
- dictionary = Dictionaries.const_get(module_name)
37
- dictionary.list_all
38
- rescue NameError
39
- raise_invalid_dictionary(dictionary)
41
+ def outside_creativity_bounds?
42
+ @creativity.negative? || @creativity > 10
40
43
  end
41
- end
42
44
 
43
- def word_list(dictionary)
44
- case dictionary
45
- when Array
46
- dictionary if dictionary.all? { |item| item.is_a?(String) }
47
- when Symbol
48
- match_word_list(dictionary)
49
- else
50
- raise ArgumentError, 'Dictionary contains invalid dictionary type'
45
+ def match_word_list(dictionary)
46
+ module_name = camelize_dictionary(dictionary)
47
+ begin
48
+ dictionary = Dictionaries.const_get(module_name)
49
+ dictionary.list_all
50
+ rescue NameError
51
+ raise_invalid_dictionary(dictionary)
52
+ end
51
53
  end
52
- end
53
54
 
54
- def random_seeded_float
55
- seed_value = Seed.generate_seed(@seed)
55
+ def word_list(dictionary)
56
+ case dictionary
57
+ when Array
58
+ dictionary if dictionary.all? { |item| item.is_a?(String) }
59
+ when Symbol
60
+ match_word_list(dictionary)
61
+ else
62
+ raise ArgumentError, 'Dictionary contains invalid dictionary type'
63
+ end
64
+ end
56
65
 
57
- prng = @seed.nil? ? Random.new : Random.new(seed_value)
58
- prng.rand
59
- end
66
+ def random_seeded_float
67
+ seed_value = Seed.generate_seed(@seed)
60
68
 
61
- def map_dictionaries(dictionaries)
62
- dictionaries.map { |dictionary| word_list(dictionary) }
63
- end
69
+ prng = @seed.nil? ? Random.new : Random.new(seed_value)
70
+ prng.rand
71
+ end
64
72
 
65
- def split_with_separator(word)
66
- if @separator.nil?
67
- word.split(/(?=[A-Z])/)
68
- else
69
- word.split(@separator)
73
+ def map_dictionaries(dictionaries)
74
+ dictionaries.map { |dictionary| word_list(dictionary) }
70
75
  end
71
- end
72
76
 
73
- def format_parts(parts)
74
- parts.map do |part|
75
- if part.match?(/[^a-zA-Z]/) && @style == :capital
76
- # Preserve original capitalization for parts with non-letter characters
77
- part
77
+ def split_with_separator(word)
78
+ if @separator.nil?
79
+ word.split(/(?=[A-Z])/)
78
80
  else
79
- format_word(part, @style)
81
+ word.split(@separator)
80
82
  end
81
- end.join(@separator)
82
- end
83
+ end
83
84
 
84
- def format_multi_word(word, original_word)
85
- if original_word.include?(' ') || original_word.include?('-')
86
- parts = split_with_separator(word)
87
- format_parts(parts)
88
- else
89
- format_word(word, @style)
85
+ def format_parts(parts)
86
+ parts.map do |part|
87
+ if part.match?(/[^a-zA-Z]/) && @style == :capital
88
+ # Preserve original capitalization for parts with non-letter characters
89
+ part
90
+ else
91
+ format_word(part, @style)
92
+ end
93
+ end.join(@separator)
90
94
  end
91
- end
92
95
 
93
- def generate_name(dictionaries)
94
- if @creativity.nil? || @creativity.zero?
95
- generate_name_original(dictionaries)
96
- else
97
- generate_name_creatively(dictionaries)
96
+ def format_multi_word(word, original_word)
97
+ if original_word.include?(' ') || original_word.include?('-')
98
+ parts = split_with_separator(word)
99
+ format_parts(parts)
100
+ else
101
+ format_word(word, @style)
102
+ end
98
103
  end
99
- end
100
104
 
101
- def generate_name_original(dictionaries)
102
- map_dictionaries(dictionaries).reduce(nil) do |acc, x|
103
- rnd = (random_seeded_float * x.length).floor
104
- original_word = x[rnd]
105
+ def generate_name(dictionaries)
106
+ if @creativity.nil? || @creativity.zero?
107
+ generate_name_original(dictionaries)
108
+ else
109
+ generate_name_creatively(dictionaries)
110
+ end
111
+ end
105
112
 
106
- output_word(acc, original_word)
113
+ def generate_name_original(dictionaries)
114
+ map_dictionaries(dictionaries).reduce(nil) do |acc, x|
115
+ rnd = (random_seeded_float * x.length).floor
116
+ original_word = x[rnd]
117
+
118
+ output_word(acc, original_word)
119
+ end
107
120
  end
108
- end
109
121
 
110
- def generate_name_creatively(dictionaries)
111
- word_lists = map_dictionaries(dictionaries)
122
+ def generate_name_creatively(dictionaries)
123
+ word_lists = map_dictionaries(dictionaries)
112
124
 
113
- word_lists.each_with_index.reduce(nil) do |acc, (word_list, index)|
114
- creativity = calculate_creativity(index)
115
- rnd = (random_seeded_float * word_list.length * creativity).floor
116
- original_word = word_list[rnd % word_list.length] # Ensure we don't go out of bounds
125
+ word_lists.each_with_index.reduce(nil) do |acc, (word_list, index)|
126
+ creativity = calculate_creativity(index)
127
+ rnd = (random_seeded_float * word_list.length * creativity).floor
128
+ original_word = word_list[rnd % word_list.length] # Ensure we don't go out of bounds
117
129
 
118
- output_word(acc, original_word)
130
+ output_word(acc, original_word)
131
+ end
119
132
  end
120
- end
121
133
 
122
- def output_word(acc, original_word)
123
- word = format_with_separator(original_word)
124
- word = format_multi_word(word, original_word)
134
+ def output_word(acc, original_word)
135
+ word = format_with_separator(original_word)
136
+ word = format_multi_word(word, original_word)
125
137
 
126
- if acc
127
- "#{acc}#{@separator}#{word}"
128
- else
129
- word
138
+ if acc
139
+ "#{acc}#{@separator}#{word}"
140
+ else
141
+ word
142
+ end
130
143
  end
131
- end
132
144
 
133
- def calculate_creativity(index)
134
- if index.zero?
135
- @creativity # Base creativity for the first dictionary
136
- else
137
- @creativity * (2 + index * 0.5) # Increase creativity for subsequent dictionaries
145
+ def calculate_creativity(index)
146
+ if index.zero?
147
+ @creativity # Base creativity for the first dictionary
148
+ else
149
+ @creativity * (2 + index * 0.5) # Increase creativity for subsequent dictionaries
150
+ end
138
151
  end
139
- end
140
152
 
141
- def camelize_dictionary(dictionary)
142
- dictionary.to_s.split('_').map(&:capitalize).join
143
- end
153
+ def camelize_dictionary(dictionary)
154
+ dictionary.to_s.split('_').map(&:capitalize).join
155
+ end
144
156
 
145
- def raise_invalid_dictionary(dictionary)
146
- raise ArgumentError, "Invalid dictionary: #{dictionary}"
147
- end
157
+ def raise_invalid_dictionary(dictionary)
158
+ raise ArgumentError, "Invalid dictionary #{dictionary}"
159
+ end
148
160
 
149
- def format_with_separator(word)
150
- if @separator.nil?
151
- # If separator is empty, just remove spaces without changing case
152
- word.gsub(/\s+/, '')
153
- else
154
- # If there's a separator, use it to replace spaces
155
- word.gsub(/\s+/, @separator)
161
+ def format_with_separator(word)
162
+ if @separator.nil?
163
+ # If separator is empty, just remove spaces without changing case
164
+ word.gsub(/\s+/, '')
165
+ else
166
+ # If there's a separator, use it to replace spaces
167
+ word.gsub(/\s+/, @separator)
168
+ end
156
169
  end
157
- end
158
170
 
159
- def format_word(word, style)
160
- case style
161
- when :lowercase
162
- word.downcase
163
- when :uppercase
164
- word.upcase
165
- when :capital
166
- word.capitalize
167
- else
168
- word
171
+ def format_word(word, style)
172
+ case style
173
+ when :lowercase
174
+ word.downcase
175
+ when :uppercase
176
+ word.upcase
177
+ when :capital
178
+ word.capitalize
179
+ else
180
+ word
181
+ end
169
182
  end
170
183
  end
171
-
172
- private_class_method(
173
- *%i[
174
- generate_name
175
- match_word_list
176
- word_list
177
- random_seeded_float
178
- map_dictionaries
179
- camelize_dictionary
180
- raise_invalid_dictionary
181
- format_with_separator
182
- format_multi_word
183
- format_parts
184
- format_word
185
- split_with_separator
186
- generate_name_original
187
- generate_name_creatively
188
- calculate_creativity
189
- output_word
190
- ]
191
- )
192
184
  end
@@ -15,7 +15,8 @@ Gem::Specification.new do |s|
15
15
  s.email = 'jongirard03@gmail.com'
16
16
  s.homepage = 'https://github.com/jongirard/unique_names_generator_ruby'
17
17
  s.metadata = { 'homepage_uri' => 'https://github.com/jongirard/unique_names_generator_ruby',
18
- 'source_code_uri' => 'https://github.com/jongirard/unique_names_generator_ruby' }
18
+ 'source_code_uri' => 'https://github.com/jongirard/unique_names_generator_ruby',
19
+ 'documentation_uri' => 'https://www.rubydoc.info/gems/unique_names_generator/' }
19
20
  s.require_paths = ['lib']
20
21
  s.license = 'MIT'
21
22
  s.files = Dir.chdir(File.expand_path(__dir__)) do
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: unique_names_generator
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jon Girard
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-07-05 00:00:00.000000000 Z
11
+ date: 2024-07-06 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rspec
@@ -34,6 +34,7 @@ extensions: []
34
34
  extra_rdoc_files: []
35
35
  files:
36
36
  - ".github/workflows/ruby.yml"
37
+ - ".gitignore"
37
38
  - ".pryrc"
38
39
  - ".rspec"
39
40
  - ".rubocop.yml"
@@ -59,6 +60,7 @@ licenses:
59
60
  metadata:
60
61
  homepage_uri: https://github.com/jongirard/unique_names_generator_ruby
61
62
  source_code_uri: https://github.com/jongirard/unique_names_generator_ruby
63
+ documentation_uri: https://www.rubydoc.info/gems/unique_names_generator/
62
64
  post_install_message:
63
65
  rdoc_options: []
64
66
  require_paths: