randomperson 1.3.0 → 1.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 +7 -0
- data/.gitignore +4 -0
- data/.rspec +1 -1
- data/.travis.yml +1 -2
- data/CHANGELOG.md +16 -0
- data/Gemfile +13 -0
- data/LICENCE +19 -0
- data/README.markdown +4 -22
- data/Rakefile +1 -1
- data/lib/randomperson.rb +35 -14
- data/lib/randomperson/demographic.rb +38 -29
- data/lib/randomperson/generator.rb +10 -4
- data/lib/randomperson/loader.rb +24 -12
- data/lib/randomperson/name.rb +1 -1
- data/lib/randomperson/outputter.rb +36 -5
- data/lib/randomperson/ratio.rb +7 -2
- data/lib/randomperson/version.rb +4 -1
- data/randomperson.gemspec +2 -7
- data/spec/last_and_first_names_spec.rb +19 -8
- data/spec/randomperson_spec.rb +151 -178
- data/spec/spec_helper.rb +11 -2
- data/spec/support/shared_examples/names.rb +2 -2
- metadata +17 -122
- data/lib/randomperson/ext/date.rb +0 -16
- data/lib/randomperson/ext/hash.rb +0 -6
- data/lib/randomperson/ext/kernel.rb +0 -21
- data/lib/randomperson/ext/set.rb +0 -15
- data/lib/randomperson/ext/string.rb +0 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 1684642d6e98a13f159efde26ebe53651d96da4d
|
4
|
+
data.tar.gz: 6f28d8aa62754e2846598656b2437dd747988e90
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 261270fc67ef91ae518840afd78cb2ccb2519e5409688998752e56bf129538f030d1c4136397ea6f8b880268676d9f938170b1b964feb5fc415159d9f4d72a25
|
7
|
+
data.tar.gz: 7c3831ddaf8ea131f4480c7eee0cd9c393e9ba8585b4e8e04f2aecfd4ba6a1dbab68e5ae0c1bb6d83990e0695056ea671a15ee305a46c57478e643a82cb80c64
|
data/.gitignore
CHANGED
data/.rspec
CHANGED
@@ -1,2 +1,2 @@
|
|
1
1
|
--color
|
2
|
-
--format
|
2
|
+
--format documentation
|
data/.travis.yml
CHANGED
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,19 @@
|
|
1
|
+
v 1.4.0 Friday the 27th of January 2017
|
2
|
+
|
3
|
+
* Moved officially to >= Ruby v2.0.0
|
4
|
+
* Fixed the specs to work with RSpec 3.5 and thus Travis.
|
5
|
+
* Added a lot more yard docs.
|
6
|
+
* Removed the monkey patches.
|
7
|
+
* Pruned a few internals here and there.
|
8
|
+
|
9
|
+
----
|
10
|
+
|
11
|
+
v.1.3.1 Tuesday the 24th of January 2017
|
12
|
+
|
13
|
+
* Moved the licence file to its own file for clarity. Thanks to Chad Perrin for asking for this, it was definitely needed.
|
14
|
+
|
15
|
+
----
|
16
|
+
|
1
17
|
v1.3.0 Tuesday the 11th of September 2012
|
2
18
|
|
3
19
|
* Quicker to get data out if you're not bothered about the demographic make up.
|
data/Gemfile
CHANGED
data/LICENCE
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
Copyright (c) 2012 Iain Barnett
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
4
|
+
of this software and associated documentation files (the "Software"), to deal
|
5
|
+
in the Software without restriction, including without limitation the rights
|
6
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
7
|
+
copies of the Software, and to permit persons to whom the Software is
|
8
|
+
furnished to do so, subject to the following conditions:
|
9
|
+
|
10
|
+
The above copyright notice and this permission notice shall be included in
|
11
|
+
all copies or substantial portions of the Software.
|
12
|
+
|
13
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
14
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
15
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
16
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
17
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
18
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
19
|
+
THE SOFTWARE.
|
data/README.markdown
CHANGED
@@ -264,7 +264,7 @@ If you need to check what's loaded, use `loaded_classes`
|
|
264
264
|
|
265
265
|
r.demographics["French"].loaded_classes
|
266
266
|
|
267
|
-
|
267
|
+
# => {:femalefirst=>"French_Female_First", :last=>"French_Last", :malefirst=>"French_Male_First"}
|
268
268
|
|
269
269
|
Or, see all the demographics' loaded classes:
|
270
270
|
|
@@ -476,29 +476,11 @@ Special thanks to my agent, all the people at Marvel and DC for such fine comics
|
|
476
476
|
|
477
477
|
## LICENCE:
|
478
478
|
|
479
|
-
|
480
|
-
|
481
|
-
Copyright (c) 2012 Iain Barnett
|
482
|
-
|
483
|
-
Permission is hereby granted, free of charge, to any person obtaining a copy
|
484
|
-
of this software and associated documentation files (the "Software"), to deal
|
485
|
-
in the Software without restriction, including without limitation the rights
|
486
|
-
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
487
|
-
copies of the Software, and to permit persons to whom the Software is
|
488
|
-
furnished to do so, subject to the following conditions:
|
479
|
+
See the LICENCE file.
|
489
480
|
|
490
|
-
|
491
|
-
all copies or substantial portions of the Software.
|
492
|
-
|
493
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
494
|
-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
495
|
-
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
496
|
-
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
497
|
-
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
498
|
-
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
499
|
-
THE SOFTWARE.
|
481
|
+
It's an MIT Licence, I didn't take any code from the Perl one just names and a slight idea on how to structure things, so this ain't gonna be under the GPL. MIT is better anyway ;)
|
500
482
|
|
501
|
-
|
483
|
+
Please, when using this code, be good.
|
502
484
|
|
503
485
|
|
504
486
|
|
data/Rakefile
CHANGED
data/lib/randomperson.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# encoding: UTF-8
|
2
2
|
|
3
|
-
|
3
|
+
# A library for generating random names
|
4
4
|
module RandomPerson
|
5
5
|
|
6
6
|
#require all the scaffolding
|
@@ -9,12 +9,6 @@ module RandomPerson
|
|
9
9
|
require 'date'
|
10
10
|
|
11
11
|
require_relative './randomperson/version.rb'
|
12
|
-
require_relative './randomperson/ext/array.rb'
|
13
|
-
require_relative './randomperson/ext/date.rb'
|
14
|
-
require_relative './randomperson/ext/enumerable.rb'
|
15
|
-
require_relative './randomperson/ext/hash.rb'
|
16
|
-
require_relative './randomperson/ext/kernel.rb'
|
17
|
-
require_relative './randomperson/ext/set.rb'
|
18
12
|
|
19
13
|
require_relative './randomperson/demographic.rb'
|
20
14
|
require_relative './randomperson/generator.rb'
|
@@ -22,7 +16,11 @@ module RandomPerson
|
|
22
16
|
require_relative './randomperson/person.rb'
|
23
17
|
#require_relative './randomperson/ratio.rb'
|
24
18
|
|
19
|
+
|
20
|
+
# A slightly modified Hash to keep track of loaded classes.
|
25
21
|
class DemoHash < Hash
|
22
|
+
|
23
|
+
# @return [Hash]
|
26
24
|
def loaded_classes
|
27
25
|
if @loaded_classes.nil?
|
28
26
|
@loaded_classes = Hash.new
|
@@ -33,16 +31,21 @@ module RandomPerson
|
|
33
31
|
@loaded_classes
|
34
32
|
end
|
35
33
|
|
36
|
-
|
34
|
+
|
35
|
+
# @see Hash#store
|
37
36
|
alias :"[]=" :store
|
38
37
|
|
38
|
+
|
39
|
+
# @see Hash#store
|
39
40
|
def store( key, value )
|
40
41
|
@loaded_classes ||= Hash.new
|
41
42
|
@loaded_classes[key] = value
|
42
|
-
old_store key, value
|
43
|
+
old_store.bind(self).call key, value
|
43
44
|
end
|
44
45
|
end
|
45
46
|
|
47
|
+
|
48
|
+
# Wrapper for convenience.
|
46
49
|
class Facade
|
47
50
|
|
48
51
|
# @return [Hash{String => RandomPerson::Demographic}]
|
@@ -50,11 +53,13 @@ module RandomPerson
|
|
50
53
|
@demos ||= DemoHash.new
|
51
54
|
end
|
52
55
|
|
56
|
+
|
53
57
|
# @return [Hash]
|
54
58
|
def loaded_classes
|
55
59
|
demographics.loaded_classes
|
56
60
|
end
|
57
61
|
|
62
|
+
|
58
63
|
#class instance variable to keep track of generators
|
59
64
|
def generators
|
60
65
|
@generators ||= {}
|
@@ -85,14 +90,15 @@ module RandomPerson
|
|
85
90
|
@person = nil
|
86
91
|
@last_demo_name = nil
|
87
92
|
end
|
88
|
-
|
93
|
+
|
94
|
+
|
89
95
|
alias :reset :clear
|
90
96
|
attr_accessor :last_demo_name
|
91
97
|
|
92
98
|
|
93
99
|
# The last person generated.
|
94
100
|
# If a demographic name is given that is different to the last then a new person is generated. If no name is given then the last is used.
|
95
|
-
# @param [String,Symbol,Integer]
|
101
|
+
# @param [String,Symbol,Integer] demo_name The key for retrieving the demographic.
|
96
102
|
# @param [#call] block Error handler for when a key is given that does not exist.
|
97
103
|
# @return [RandomPerson::Person]
|
98
104
|
def person( demo_name=nil, &block )
|
@@ -123,7 +129,10 @@ module RandomPerson
|
|
123
129
|
end
|
124
130
|
|
125
131
|
|
126
|
-
|
132
|
+
# Generate a new demographic
|
133
|
+
# @param [#to_s] demo_name A name for the demographic.
|
134
|
+
# @param [#call] block
|
135
|
+
# @return [RandomPerson::Demographic]
|
127
136
|
def generate( demo_name=nil, &block )
|
128
137
|
ds = gen_new( demo_name, &block )
|
129
138
|
ds.nil? ? nil : ds.first
|
@@ -135,29 +144,35 @@ module RandomPerson
|
|
135
144
|
def generate_demo
|
136
145
|
Demographic.load
|
137
146
|
yesses = %w{prefix suffix female -male last}.map {|word|
|
138
|
-
Demographic.
|
147
|
+
Demographic.classify_true(word).to_a.sample
|
139
148
|
}
|
140
149
|
demo = self.demographic
|
141
150
|
demo.require_and_add yesses
|
142
151
|
[demo.name, demo]
|
143
152
|
end
|
144
153
|
|
154
|
+
|
155
|
+
# The default default error block :)
|
145
156
|
DEFAULT_gen_new_BLOCK = ->(error) {
|
146
157
|
warn error.message
|
147
158
|
}
|
148
159
|
|
149
160
|
|
161
|
+
# This holds the default error block
|
150
162
|
def self.default_error_block
|
151
163
|
@default_gen_new_error_block ||= DEFAULT_gen_new_BLOCK
|
152
164
|
end
|
153
165
|
|
166
|
+
|
167
|
+
# Set the default error block
|
168
|
+
# @param [#call] block
|
154
169
|
def self.default_error_block=( block )
|
155
170
|
@default_gen_new_error_block = block
|
156
171
|
end
|
157
172
|
|
158
173
|
|
159
174
|
# If not given a demographic's name then the *last demographic defined* will be used. If there is no demographic already defined a new one will be created. If a key is given but does not exist then the supplied block will be called. If no block is given an exception will be raised.
|
160
|
-
# @param [String,Symbol,Integer]
|
175
|
+
# @param [String,Symbol,Integer] demo_name The key for retrieving the demographic.
|
161
176
|
# @param [#call] block Default for when a key is given that does not exist.
|
162
177
|
def gen_new( demo_name=nil, &block )
|
163
178
|
block = self.class.default_error_block if block.nil?
|
@@ -192,6 +207,12 @@ module RandomPerson
|
|
192
207
|
|
193
208
|
end
|
194
209
|
|
210
|
+
# Convenience method.
|
211
|
+
# @example
|
212
|
+
# require 'randomperson'
|
213
|
+
# r = RandomPerson() # don't forget the brackets!
|
214
|
+
# r.generate # => each time this will generate a new person.
|
215
|
+
# @return [RandomPerson::Facade]
|
195
216
|
def RandomPerson
|
196
217
|
RandomPerson::Facade.new
|
197
218
|
end
|
@@ -1,27 +1,10 @@
|
|
1
1
|
# encoding: UTF-8
|
2
2
|
|
3
3
|
require_relative "./loader.rb"
|
4
|
-
require_relative "./ext/set.rb"
|
5
|
-
|
6
|
-
|
7
4
|
|
8
5
|
module RandomPerson
|
9
|
-
class Constant < String
|
10
|
-
|
11
|
-
def to_constant
|
12
|
-
names = split('::')
|
13
|
-
names.shift if names.empty? || names.first.empty?
|
14
|
-
|
15
|
-
constant = Object
|
16
|
-
names.each do |name|
|
17
|
-
constant = constant.const_defined?(name) ? constant.const_get(name) : constant.const_missing(name)
|
18
|
-
end
|
19
|
-
constant
|
20
|
-
end
|
21
|
-
|
22
|
-
end
|
23
|
-
|
24
6
|
|
7
|
+
# Handles the demographics
|
25
8
|
class Demographic
|
26
9
|
include Loader
|
27
10
|
|
@@ -29,6 +12,7 @@ module RandomPerson
|
|
29
12
|
attr_accessor :name
|
30
13
|
|
31
14
|
|
15
|
+
# A hash of all the loaded classes.
|
32
16
|
def loaded_classes
|
33
17
|
@loaded_classes ||= {}
|
34
18
|
end
|
@@ -42,8 +26,22 @@ module RandomPerson
|
|
42
26
|
alias :female_first :femalefirst
|
43
27
|
|
44
28
|
|
45
|
-
|
46
|
-
|
29
|
+
class << self
|
30
|
+
|
31
|
+
# The available name files!
|
32
|
+
# @return [Set]
|
33
|
+
def available_name_files
|
34
|
+
@available_name_files ||= Set.new
|
35
|
+
end
|
36
|
+
|
37
|
+
|
38
|
+
# @todo handle failure
|
39
|
+
# @return [Set] The set for which the pattern matches.
|
40
|
+
def classify_true( pattern )
|
41
|
+
available_name_files.classify{|s|
|
42
|
+
true if s =~ %r{^.*/[^/]*#{pattern}[^/]*$}i
|
43
|
+
}[true]
|
44
|
+
end
|
47
45
|
end
|
48
46
|
|
49
47
|
|
@@ -101,15 +99,17 @@ module RandomPerson
|
|
101
99
|
end
|
102
100
|
|
103
101
|
|
102
|
+
# Requires the name files and adds them to the loaded file hash.
|
103
|
+
# @api private
|
104
104
|
def require_and_add( yesses )
|
105
|
-
yesses.
|
105
|
+
yesses.each {|file_name|
|
106
106
|
require file_name
|
107
|
-
|
108
|
-
}.each do |klass|
|
107
|
+
klass = Kernel.const_get( Demographic.translate file_name )
|
109
108
|
addklass klass
|
110
|
-
|
109
|
+
}
|
111
110
|
end
|
112
|
-
|
111
|
+
|
112
|
+
|
113
113
|
# tribe, gender, position
|
114
114
|
def method_missing( name, *args )
|
115
115
|
return super( name, *args ) unless name.to_s =~ /^add/
|
@@ -117,17 +117,26 @@ module RandomPerson
|
|
117
117
|
words = get_words( name )
|
118
118
|
|
119
119
|
nots = get_nots( words ).map{|word|
|
120
|
-
|
121
|
-
}.
|
120
|
+
self.class.classify_true word
|
121
|
+
}.inject(:&)
|
122
122
|
|
123
123
|
yesses = get_yesses( words ).map{|word|
|
124
|
-
|
125
|
-
}.
|
124
|
+
self.class.classify_true word
|
125
|
+
}.inject(:&)
|
126
126
|
|
127
127
|
require_and_add yesses
|
128
128
|
|
129
129
|
self # just because
|
130
130
|
end
|
131
|
+
|
132
|
+
|
133
|
+
# Be nice.
|
134
|
+
# @api private
|
135
|
+
def respond_to_missing?(name, include_private = false)
|
136
|
+
self.class.method_defined?(name) or
|
137
|
+
name.to_s =~ /^add/ or
|
138
|
+
super
|
139
|
+
end
|
131
140
|
|
132
141
|
|
133
142
|
end
|
@@ -1,5 +1,7 @@
|
|
1
1
|
module RandomPerson
|
2
2
|
|
3
|
+
# Handles the generation of a new person.
|
4
|
+
# It's not as fun as the way humans handle this :)
|
3
5
|
module Generator
|
4
6
|
|
5
7
|
require_relative './person.rb'
|
@@ -83,12 +85,16 @@ module RandomPerson
|
|
83
85
|
def self.pick_dob( age=16 )
|
84
86
|
year = Time.now.year - age
|
85
87
|
month = rand(12) + 1;
|
86
|
-
day = rand(
|
88
|
+
day = rand( days_in_month( year, month ) ) + 1
|
87
89
|
Time.local( year, month, day )
|
88
90
|
end
|
89
91
|
|
90
|
-
|
91
|
-
|
92
|
+
# Convenience function
|
93
|
+
# @param [Integer] year
|
94
|
+
# @param [Integer] month
|
95
|
+
# @return [Integer]
|
96
|
+
def self.days_in_month( year, month )
|
97
|
+
::Date.civil(year, month, -1).day
|
98
|
+
end
|
92
99
|
end
|
93
|
-
|
94
100
|
end
|
data/lib/randomperson/loader.rb
CHANGED
@@ -1,8 +1,5 @@
|
|
1
1
|
# encoding: UTF-8
|
2
2
|
|
3
|
-
require_relative "./ext/kernel.rb"
|
4
|
-
|
5
|
-
|
6
3
|
module RandomPerson
|
7
4
|
|
8
5
|
# This module is here to do the loading of data into a demographic class
|
@@ -10,9 +7,12 @@ module RandomPerson
|
|
10
7
|
module Loader
|
11
8
|
|
12
9
|
|
10
|
+
# Class methods
|
11
|
+
# @api private
|
13
12
|
module ClassMethods
|
14
13
|
|
15
|
-
|
14
|
+
# Loads the names, unsurprisingly.
|
15
|
+
# @api private
|
16
16
|
def load_names( opts={} )
|
17
17
|
opts = { patterns: ['*.rb'], lib_dir: File.dirname(__FILE__) }.merge( opts )
|
18
18
|
|
@@ -31,27 +31,39 @@ module RandomPerson
|
|
31
31
|
|
32
32
|
|
33
33
|
end # ClassMethods
|
34
|
-
|
35
|
-
|
34
|
+
|
35
|
+
|
36
|
+
# Instance methods
|
37
|
+
# @api private
|
36
38
|
module InstanceMethods
|
37
39
|
|
38
40
|
# The patterns are there to stop other files being added by accident.
|
39
41
|
# and to load the right names into the right instance var
|
40
42
|
# @todo remove evil
|
41
43
|
# @param [#to_constant] klass
|
42
|
-
|
43
|
-
|
44
|
+
# @api private
|
45
|
+
def addklass( klass, patterns=nil )
|
46
|
+
patterns ||= [
|
47
|
+
["Male",'First'],
|
48
|
+
["Female", "First"],
|
49
|
+
['Last'], ['Prefix'],
|
50
|
+
['Suffix']
|
51
|
+
]
|
44
52
|
patterns.each do |ps|
|
45
|
-
if ps.all?{|p| klass =~ /#{p}/ }
|
46
|
-
|
47
|
-
|
53
|
+
if ps.all?{|p| klass.name =~ /#{p}/ }
|
54
|
+
send "#{ps.join.downcase}=", klass.new
|
55
|
+
loaded_classes.store ps.join.downcase.to_sym, klass.name.split("::").last.scan( /[A-Z][a-z]+/ ).flatten.join("_")
|
48
56
|
end # if
|
49
57
|
end
|
50
58
|
klass
|
51
59
|
end # addklass
|
52
60
|
|
53
61
|
end # InstanceMethods
|
54
|
-
|
62
|
+
|
63
|
+
|
64
|
+
# Classic hooking
|
65
|
+
# @param [Class] receiver
|
66
|
+
# @api private
|
55
67
|
def self.included(receiver)
|
56
68
|
receiver.extend ClassMethods
|
57
69
|
receiver.send :include, InstanceMethods
|