randomperson 1.3.0 → 1.4.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|