randomexp 0.1.7

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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: f4ed76ede990b9650d5c9331fe59588474d2cde7e0db2c6d2498419141addcb6
4
+ data.tar.gz: 68521de0cdd541576301d925caa1f96d5cd880ec5450ee36d2ae1a6bd39a3f47
5
+ SHA512:
6
+ metadata.gz: '081fcebdacd959ddefc4efa2f4cef6bb33bc90bc7d1ce9fc0eced2125ca2d8452936ee3ec46af276d3b44a8c2e88e4be68479c17c2e7d1b56b8af5ae3ed8f469'
7
+ data.tar.gz: 3ee83fbb22614b931d84efbbad75330543dd5392f9823f55bd1bd0767aafaf0979e2d79320ab8cbd636a16c9a5c210309599396111a0edbf2e17709baa3b71c7
data/.gitignore ADDED
@@ -0,0 +1,9 @@
1
+ coverage/*
2
+ pkg/*
3
+ rdoc/*
4
+ gbin
5
+ vendor
6
+ .bundle
7
+ Gemfile.lock
8
+ .rvmrc
9
+
data/CHANGELOG ADDED
@@ -0,0 +1,20 @@
1
+ == 0.1.4 "Wally Wisoky" 2008-10-08
2
+ * Added realistic name generation (Matt Aimonetti)
3
+ * Fixed loadpath issues (Gerrit Kaiser)
4
+
5
+ == 0.1.3 "Oological" 2008-07-08
6
+ * Randgen.word should not return a string that does not match /^\w+$/
7
+
8
+ == 0.1.2 "I'm Not Saying It's Not Beta"
9
+ * Changed rand to Kernel#rand to avoid conflicting with rails (thanks agile!)
10
+
11
+ == 0.1.1 "Still Quite Beta" 2008-07-20
12
+ * Added Range#of method.
13
+ * Heavy refactoring of the Parser.parse method.
14
+ * Fixed the /\./ bug.
15
+
16
+ == 0.1.0 "Very Beta" 2008-07-08
17
+ * Initial version of randomexp!
18
+ * Has support for very simple regular expressions.
19
+ * Randgen has limited methods.
20
+ * Dictionary is reading from the local words file.
data/Gemfile ADDED
@@ -0,0 +1,7 @@
1
+ source "http://rubygems.org"
2
+
3
+ group :test do
4
+ gem 'rspec'
5
+ gem 'rake'
6
+ gem 'simplecov'
7
+ end
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2021-2022 Naresh Sekar
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README ADDED
@@ -0,0 +1,82 @@
1
+ Randomexp
2
+ by Naresh Sekar
3
+ http://github.com/nareshnavinash/randomexp
4
+
5
+ == DESCRIPTION:
6
+
7
+ andexp makes it easy to generate random string from most regular expressions.
8
+
9
+ == REQUIREMENTS:
10
+
11
+ * none!
12
+
13
+ == INSTALL:
14
+
15
+ $ sudo gem install randomexp
16
+
17
+ == USAGE:
18
+
19
+ Randomexp adds the #generate (or #gen, for short) method to the Regexp class,
20
+ which generates a 'random' string that will match your regular expression.
21
+
22
+ /abc|def/.gen
23
+ # => "def"
24
+
25
+ == Valid Regexp's
26
+
27
+ Randomexp can only generate matching string from simple regular expression.
28
+ Except for a few circumstances, wildcards are generally not allowed in the
29
+ regular expression. is pretty domain specific, so trying to guess when to
30
+ terminate a random pattern would produce unhelpful data:
31
+
32
+ >> /Aa{3}h*!/.gen
33
+ # => RuntimeError: Sorry, "h*" is too vague, try setting a range: "h{0,3}"
34
+ >> /Aa{3}h{3,15}!/.gen
35
+ => "Aaaahhhhh!"
36
+
37
+ >> /(never gonna (give you up|let you down), )*/.gen
38
+ => RuntimeError: Sorry, "(...)*" is too vague, try setting a range: "(...){0, 3}"
39
+ >> /(never gonna (give you up|let you down), ){3,5}/.gen
40
+ => "never gonna give you up, never gonna let you down, never gonna give you up, never gonna give you up, "
41
+
42
+ The exception being word characters (\w), which generate a random word from the Dictionary class.
43
+
44
+ >> /\w+/.gen
45
+ => "groveling"
46
+
47
+ = Primitives & Complex matches
48
+
49
+ The single character matchers supported are words(\w), whitespace(\s), and digits(\d).
50
+
51
+ >> /\d{50}/.gen
52
+ => "50315410741096763188525493528315906035878741451037"
53
+
54
+ When a multiplicity constraint is placed on a word character, a word with the valid length is generated.
55
+
56
+ >> /\w{10}/.gen # a word with 10 letters
57
+ => "Chaucerism"
58
+
59
+ >> /\w{5,15}/.gen
60
+ => "cabalistic"
61
+
62
+ Complex matchers use the [:...:] syntax within the regular expression.
63
+
64
+ >> /[:sentence:]/.gen
65
+ => "Nonhearer demetricize toppiece filicic possessedness rhodizite zoomagnetism earwigginess steady"
66
+
67
+ Complex matchers can also be added by extending the Randgen class.
68
+
69
+ class Randgen
70
+ def self.serial_number(options = {})
71
+ /XX\d{4}-\w-\d{5}/.gen
72
+ end
73
+ end
74
+
75
+ >> /[:serial_number:]/.gen
76
+ => "XX3770-M-33114"
77
+
78
+ = Dictionary
79
+
80
+ The Dictionary loads the local users' words file, allowing randomly generated words to be chosen from
81
+ thousands of entries to the words file. Words are mapped by their length to allow words to be randomly
82
+ chosen based on size.
data/Rakefile ADDED
@@ -0,0 +1,76 @@
1
+ require 'rubygems/package_task'
2
+ require 'rubygems/specification'
3
+ require 'date'
4
+ require 'rspec/core/rake_task'
5
+
6
+ PROJECT_NAME = "randomexp"
7
+ GEM = "randomexp"
8
+ GEM_VERSION = "0.1.6"
9
+ AUTHOR = "Naresh Sekar"
10
+ EMAIL = "nareshnavinash@gmail.com"
11
+ HOMEPAGE = "http://github.com/nareshnavinash/randomexp"
12
+ TITLE = "Randomexp Gem"
13
+ SUMMARY = "Library for generating random strings."
14
+ FILES = %w(LICENSE README Rakefile TODO CHANGELOG) + Dir.glob("{lib,spec}/**/*") + Dir.glob("wordlists/**/*")
15
+ RDOC_FILES = %w(LICENSE README Rakefile TODO CHANGELOG) + Dir.glob("lib/**/*")
16
+
17
+ task :default => :specs
18
+
19
+ spec = Gem::Specification.new do |s|
20
+ s.name = GEM
21
+ s.version = GEM_VERSION
22
+ s.platform = Gem::Platform::RUBY
23
+ s.has_rdoc = true
24
+ s.extra_rdoc_files = ["README", "LICENSE", 'TODO']
25
+ s.summary = SUMMARY
26
+ s.description = s.summary
27
+ s.author = AUTHOR
28
+ s.email = EMAIL
29
+ s.homepage = HOMEPAGE
30
+
31
+ s.require_path = 'lib'
32
+ s.autorequire = GEM
33
+ s.files = FILES
34
+ end
35
+
36
+ Gem::PackageTask.new(spec) do |package|
37
+ package.gem_spec = spec
38
+ package.need_zip = true
39
+ package.need_tar = true
40
+ end
41
+
42
+ desc "install the gem locally"
43
+ task :install => [:package] do
44
+ sh %{sudo gem install pkg/#{GEM}-#{GEM_VERSION}}
45
+ end
46
+
47
+ desc "create a gemspec file"
48
+ task :make_spec do
49
+ File.open("#{GEM}.gemspec", "w") do |file|
50
+ file.puts spec.to_ruby
51
+ end
52
+ end
53
+
54
+ ##############################################################################
55
+ # rSpec & rcov
56
+ ##############################################################################
57
+ desc "Run all unit specs"
58
+ RSpec::Core::RakeTask.new("specs:unit") do |t|
59
+ t.rspec_opts = ["--format", "documentation", "--colour"]
60
+ t.pattern = "spec/unit/**/*_spec.rb"
61
+ t.rcov_opts = %w[--sort coverage --sort-reverse]
62
+ t.rcov_opts << '--only-uncovered'
63
+ t.rcov_opts << '--output coverage/unit'
64
+
65
+ end
66
+
67
+ desc "Run all regression specs"
68
+ RSpec::Core::RakeTask.new("specs:regression") do |t|
69
+ t.rspec_opts = ["--format", "documentation", "--colour"]
70
+ t.pattern = "spec/regression/**/*_spec.rb"
71
+ t.rcov_opts = %w[--sort coverage --sort-reverse]
72
+ t.rcov_opts << '--only-uncovered'
73
+ t.rcov_opts << '--output coverage/integration'
74
+ end
75
+
76
+ task :specs => ['specs:unit', 'specs:regression']
data/TODO ADDED
@@ -0,0 +1,4 @@
1
+ == Todo list
2
+ * add a ~/.randomexp dir for configuration
3
+ * add [] syntax: /[aeiou]{4}/.gen
4
+ * more generators for Randgen
@@ -0,0 +1,5 @@
1
+ class Array
2
+ def pick_rand_value
3
+ at Kernel.rand(size)
4
+ end
5
+ end
@@ -0,0 +1,5 @@
1
+ class Integer
2
+ def of
3
+ (1..self).to_a.map { yield }
4
+ end
5
+ end
@@ -0,0 +1,9 @@
1
+ class Range
2
+ def pick_rand_value
3
+ to_a.pick_rand_value
4
+ end
5
+
6
+ def of
7
+ pick_rand_value.of { yield }
8
+ end
9
+ end
@@ -0,0 +1,7 @@
1
+ class Regexp
2
+ def generate
3
+ Randomexp.new(source).reduce
4
+ end
5
+
6
+ alias_method :gen, :generate
7
+ end
@@ -0,0 +1,6 @@
1
+ dir = File.dirname(__FILE__)
2
+
3
+ require dir + '/core_ext/array'
4
+ require dir + '/core_ext/integer'
5
+ require dir + '/core_ext/range'
6
+ require dir + '/core_ext/regexp'
@@ -0,0 +1,32 @@
1
+ class Randomexp::Dictionary
2
+ def self.file_paths
3
+ @dictionary_path ||= %w[/usr/share/dict/words /usr/dict/words ~/.dict/words]
4
+ end
5
+
6
+ def self.register(path)
7
+ file_paths.unshift(path)
8
+ end
9
+
10
+ def self.load_dictionary
11
+ if path = file_paths.detect {|path| File.exists?(File.expand_path(path)) }
12
+ File.read(path).split
13
+ else
14
+ raise "Words file not found. Check if it is installed in (/usr/share/dict/words or /usr/dict/words) "
15
+ end
16
+ end
17
+
18
+ def self.words(options = {})
19
+ if options.has_key?(:length)
20
+ words_by_length[options[:length]]
21
+ else
22
+ @@words ||= load_dictionary
23
+ end
24
+ end
25
+
26
+ def self.words_by_length
27
+ @@words_by_length ||= begin
28
+ hash = Hash.new {|h,k| h[k] = [] }
29
+ words.inject(hash) {|h, w| h[w.size] << w; h }
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,97 @@
1
+ class Randomexp
2
+ class Parser
3
+ def self.parse(source)
4
+ case
5
+ when source =~ /^(.*)(\*|\*\?|\+|\+\?|\?)$/ && balanced?($1, $2)
6
+ parse_quantified($1, $2.to_sym) # ends with *, +, or ?: /(..)?/
7
+ when source =~ /^(.*)\{(\d+)\,(\d+)\}$/ && balanced?($1, $2)
8
+ parse_quantified($1, ($2.to_i)..($3.to_i)) #ends with a range: /(..){..,..}/
9
+ when source =~ /^(.*)\{(\d+)\}$/ && balanced?($1, $2)
10
+ parse_quantified($1, $2.to_i) #ends with a range: /..(..){..}/
11
+ when source =~ /^\((.*)\)\((.*)\)$/ && balanced?($1, $2)
12
+ union(parse($1), parse($2)) #balanced union: /(..)(..)/
13
+ when source =~ /^(\(.*\))\|(\(.*\))$/ && balanced?($1, $2)
14
+ intersection(parse($1), parse($2)) #balanced intersection: /(..)|(..)/
15
+ when source =~ /^(.*)\|(.*)$/ && balanced?($1, $2)
16
+ intersection(parse($1), parse($2)) #implied intersection: /..|../
17
+ when source =~ /^(.*)\|\((\(.*\))\)$/ && balanced?($1, $2)
18
+ intersection(parse($1), parse($2)) #unbalanced intersection: /(..)|((...))/
19
+ when source =~ /^(.+)(\(.*\))$/ && balanced?($1, $2)
20
+ union(parse($1), parse($2)) #unbalanced union: /...(...)/
21
+ when source =~ /^\((.*)\)$/ && balanced?($1)
22
+ union(parse($1)) #explicit group: /(..)/
23
+ when source =~ /^([^()]*)(\(.*\))$/ && balanced?($1, $2)
24
+ union(parse($1), parse($2)) #implied group: /..(..)/
25
+ when source =~ /^(.*)\[\:(.*)\:\]$/
26
+ union(parse($1), random($2)) #custom random: /[:word:]/
27
+ when source =~ /^(.*)\\([wsdc])$/
28
+ union(parse($1), random($2)) #reserved random: /..\w/
29
+ when source =~ /^(.*)\\(.)$/ || source =~ /(.*)(.|\s)$/
30
+ union(parse($1), literal($2)) #end with literal or space: /... /
31
+ else
32
+ nil
33
+ end
34
+ end
35
+
36
+ def self.parse_quantified(source, multiplicity)
37
+ case source
38
+ when /^[^()]*$/ then quantify_rhs(parse(source), multiplicity) #implied union: /...+/
39
+ when /^(\(.*\))$/ then quantify(parse(source), multiplicity) #group: /(...)?/
40
+ when /^(.*\))$/ then quantify_rhs(parse(source), multiplicity) #implied union: /...(...)?/
41
+ when /^(.*[^)]+)$/ then quantify_rhs(parse(source), multiplicity) #implied union: /...(...)...?/
42
+ else quantify(parse(source), multiplicity)
43
+ end
44
+ end
45
+
46
+ class << self
47
+ alias_method :[], :parse
48
+ end
49
+
50
+ def self.balanced?(*args)
51
+ args.all? {|s| s.count('(') == s.count(')')}
52
+ end
53
+
54
+ def self.quantify_rhs(sexp, multiplicity)
55
+ case sexp.first
56
+ when :union
57
+ rhs = sexp.pop
58
+ sexp << quantify(rhs, multiplicity)
59
+ else
60
+ quantify(sexp, multiplicity)
61
+ end
62
+ end
63
+
64
+ def self.quantify(lhs, sym)
65
+ [:quantify, lhs, sym]
66
+ end
67
+
68
+ def self.union(lhs, *rhs)
69
+ if lhs.nil?
70
+ union(*rhs)
71
+ elsif rhs.empty?
72
+ lhs
73
+ elsif lhs.first == :union
74
+ rhs.each {|s| lhs << s}
75
+ lhs
76
+ else
77
+ [:union, lhs, *rhs]
78
+ end
79
+ end
80
+
81
+ def self.intersection(lhs, rhs)
82
+ if rhs.first == :intersection
83
+ [:intersection, lhs] + rhs[1..-1]
84
+ else
85
+ [:intersection, lhs, rhs]
86
+ end
87
+ end
88
+
89
+ def self.random(char)
90
+ [:random, char.to_sym]
91
+ end
92
+
93
+ def self.literal(word)
94
+ [:literal, word]
95
+ end
96
+ end
97
+ end
@@ -0,0 +1,78 @@
1
+ class Randgen
2
+ WORDS_PER_SENTENCE = 3..20
3
+ SENTENCES_PER_PARAGRAPH = 3..8
4
+
5
+ def self.bool(options = {})
6
+ ['true', 'false'].pick_rand_value
7
+ end
8
+
9
+ def self.lchar(options = {})
10
+ ('a'..'z').to_a.pick_rand_value
11
+ end
12
+
13
+ def self.uchar(options = {})
14
+ ('A'..'Z').to_a.pick_rand_value
15
+ end
16
+
17
+ def self.char(options = {})
18
+ [lchar, uchar].pick_rand_value
19
+ end
20
+
21
+ def self.whitespace(options = {})
22
+ ["\t", "\n", "\r", "\f"].pick_rand_value
23
+ end
24
+
25
+ def self.digit(options = {})
26
+ ('0'..'9').to_a.pick_rand_value
27
+ end
28
+
29
+ def self.alpha_numeric(options = {})
30
+ [char, digit].pick_rand_value
31
+ end
32
+
33
+ def self.word(options = {})
34
+ begin
35
+ word = Randomexp::Dictionary.words(options).pick_rand_value
36
+ word ||= options[:length].of { alpha_numeric }.join
37
+ end until word =~ /^\w+$/
38
+
39
+ word
40
+ end
41
+
42
+ def self.first_name(options = {})
43
+ RealName.first_names(options).pick_rand_value
44
+ end
45
+
46
+ def self.surname(options = {})
47
+ RealName.surnames(options).pick_rand_value
48
+ end
49
+
50
+ class << self
51
+ alias_method :last_name, :surname
52
+ end
53
+
54
+ def self.name(options = {})
55
+ "#{first_name(options)} #{surname(options)}"
56
+ end
57
+
58
+ def self.email(options = {})
59
+ domain = options.fetch(:domain, "#{word(options)}.example.org")
60
+ "#{word(options)}@#{domain}"
61
+ end
62
+
63
+ def self.sentence(options = {})
64
+ ((options[:length] || WORDS_PER_SENTENCE.pick_rand_value).of { word } * " ").capitalize
65
+ end
66
+
67
+ def self.paragraph(options = {})
68
+ ((options[:length] || SENTENCES_PER_PARAGRAPH.pick_rand_value).of { sentence } * ". ") + "."
69
+ end
70
+
71
+ def self.phone_number(options = {})
72
+ case options[:length]
73
+ when 7 then /\d{3}-\d{4}/.gen
74
+ when 10 then /\d{3}-\d{3}-\d{4}/.gen
75
+ else /(\d{3}-)?\d{3}-\d{4}/.gen
76
+ end
77
+ end
78
+ end
@@ -0,0 +1,102 @@
1
+ class Randomexp
2
+ class Reducer
3
+ def self.reduce(sexp, quantity = nil)
4
+ send(sexp.first, sexp[1..-1], quantity)
5
+ end
6
+
7
+ class << self
8
+ alias_method :[], :reduce
9
+ end
10
+
11
+ def self.quantify(sexp, old_quantity)
12
+ reduce(*sexp)
13
+ end
14
+
15
+ def self.random(sexpish, quantity)
16
+ case s = sexpish.first
17
+ when :w then char(quantity)
18
+ when :s then whitespace(quantity)
19
+ when :d then digit(quantity)
20
+ else randgen(s, quantity)
21
+ end
22
+ end
23
+
24
+ def self.literal(cell, quantity = nil)
25
+ case quantity
26
+ when :'?' then ([''] + cell).pick_rand_value
27
+ when :+, :'+?' then raise "Sorry, \"#{cell * ''}+\" is too vague, try setting a range: \"#{cell * ''}{1,3}\""
28
+ when :*, :'*?' then raise "Sorry, \"#{cell * ''}*\" is too vague, try setting a range: \"#{cell * ''}{0,3}\""
29
+ when Range then quantity.pick_rand_value.of { cell * '' } * ''
30
+ when Integer then quantity.of { cell * '' } * ''
31
+ when nil then cell * ''
32
+ end
33
+ end
34
+
35
+ def self.intersection(cell, quantity)
36
+ case quantity
37
+ when :'?' then ['', cell.map {|s| reduce(s)}.pick_rand_value].pick_rand_value
38
+ when :+, :'+?' then raise "Sorry, \"((...)|(...))+\" is too vague, try setting a range: \"((...)|(...)){1, 3}\""
39
+ when :*, :'*?' then raise "Sorry, \"((...)|(...))*\" is too vague, try setting a range: \"((...)|(...)){0, 3}\""
40
+ when Range then quantity.pick_rand_value.of { cell.map {|s| reduce(s)}.pick_rand_value } * ''
41
+ when Integer then quantity.of { cell.map {|s| reduce(s)}.pick_rand_value } * ''
42
+ when nil then cell.map {|s| reduce(s)}.pick_rand_value
43
+ end
44
+ end
45
+
46
+ def self.union(cell, quantity)
47
+ case quantity
48
+ when :'?' then ['', cell.map {|s| reduce(s)} * ''].pick_rand_value
49
+ when :+, :'+?' then raise "Sorry, \"(...)+\" is too vague, try setting a range: \"(...){1, 3}\""
50
+ when :*, :'*?' then raise "Sorry, \"(...)*\" is too vague, try setting a range: \"(...){0, 3}\""
51
+ when Range then quantity.pick_rand_value.of { cell.map {|s| reduce(s)} * '' } * ''
52
+ when Integer then quantity.of { cell.map {|s| reduce(s)} * '' } * ''
53
+ when nil then cell.map {|s| reduce(s)} * ''
54
+ end
55
+ end
56
+
57
+ def self.char(quantity)
58
+ case quantity
59
+ when :'?' then ['', Randgen.char].pick_rand_value
60
+ when :+, :'+?' then Randgen.word
61
+ when :*, :'*?' then ['', Randgen.word].pick_rand_value
62
+ when Range then Randgen.word(:length => quantity.pick_rand_value)
63
+ when 1, nil then Randgen.char
64
+ when Integer then Randgen.word(:length => quantity)
65
+ end
66
+ end
67
+
68
+ def self.whitespace(quantity)
69
+ case quantity
70
+ when :'?' then ['', Randgen.whitespace].pick_rand_value
71
+ when :+, :'+?' then raise "Sorry, \"\\s+\" is too vague, try setting a range: \"\\s{1, 5}\""
72
+ when :*, :'*?' then raise "Sorry, \"\\s*\" is too vague, try setting a range: \"\\s{0, 5}\""
73
+ when Range then quantity.pick_rand_value.of { Randgen.whitespace } * ''
74
+ when Integer then quantity.of { Randgen.whitespace } * ''
75
+ when nil then Randgen.whitespace
76
+ end
77
+ end
78
+
79
+ def self.digit(quantity)
80
+ case quantity
81
+ when :'?' then ['', Randgen.digit].pick_rand_value
82
+ when :+, :'+?' then raise "Sorry, \"\\d+\" is too vague, try setting a range: \"\\d{1, 5}\""
83
+ when :*, :'*?' then raise "Sorry, \"\\d*\" is too vague, try setting a range: \"\\d{0, 5}\""
84
+ when Range then quantity.pick_rand_value.of { Randgen.digit } * ''
85
+ when Integer then quantity.of { Randgen.digit } * ''
86
+ when nil then Randgen.digit
87
+ end
88
+ end
89
+
90
+ def self.randgen(args, quantity)
91
+ method_name, _ = *args
92
+ case quantity
93
+ when :'?' then ['', Randgen.send(method_name, :length => 1)].pick_rand_value
94
+ when :+, :'+?' then Randgen.send(method_name)
95
+ when :*, :'*?' then ['', Randgen.send(method_name)].pick_rand_value
96
+ when Range then Randgen.send(method_name, :length => quantity.pick_rand_value)
97
+ when 1, nil then Randgen.send(method_name)
98
+ when Integer then Randgen.send(method_name, :length => quantity)
99
+ end
100
+ end
101
+ end
102
+ end
@@ -0,0 +1,3 @@
1
+ class Randomexp
2
+ VERSION = "0.1.7"
3
+ end
@@ -0,0 +1,25 @@
1
+ class RealName
2
+
3
+ def self.load_female_first_names
4
+ dir = File.dirname(__FILE__)
5
+ if File.exists?("#{dir}/../../../wordlists/female_names")
6
+ File.read("#{dir}/../../../wordlists/female_names").split
7
+ else
8
+ raise "words file not found"
9
+ end
10
+ end
11
+
12
+ def self.female_first_names(options = {})
13
+ if options.has_key?(:length)
14
+ female_first_names_by_length[options[:length]]
15
+ else
16
+ @@female_first_names ||= load_female_first_names
17
+ end
18
+ end
19
+
20
+ def self.female_first_names_by_length
21
+ @@female_first_names_by_length ||= begin
22
+ female_first_names.inject(Hash.new {|h,k| h[k] = [] }) {|h, w| (h[w.size] ||= []) << w; h }
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,25 @@
1
+ class RealName
2
+
3
+ def self.load_male_first_names
4
+ dir = File.dirname(__FILE__)
5
+ if File.exists?("#{dir}/../../../wordlists/male_names")
6
+ File.read("#{dir}/../../../wordlists/male_names").split
7
+ else
8
+ raise "words file not found"
9
+ end
10
+ end
11
+
12
+ def self.male_first_names(options = {})
13
+ if options.has_key?(:length)
14
+ male_first_names_by_length[options[:length]]
15
+ else
16
+ @@male_first_names ||= load_male_first_names
17
+ end
18
+ end
19
+
20
+ def self.male_first_names_by_length
21
+ @@male_first_names_by_length ||= begin
22
+ male_first_names.inject(Hash.new {|h,k| h[k] = [] }) {|h, w| (h[w.size] ||= []) << w; h }
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,35 @@
1
+ class RealName
2
+ def self.load_surnames
3
+ dir = File.dirname(__FILE__)
4
+ if File.exists?("#{dir}/../../../wordlists/surnames")
5
+ File.read("#{dir}/../../../wordlists/surnames").split
6
+ else
7
+ raise "words file not found"
8
+ end
9
+ end
10
+
11
+ def self.surnames(options = {})
12
+ if options.has_key?(:length)
13
+ surnames_by_length[options[:length]]
14
+ else
15
+ @@surnames ||= load_surnames
16
+ end
17
+ end
18
+
19
+ def self.surnames_by_length
20
+ @@surnames_by_length ||= begin
21
+ surnames.inject(Hash.new {|h,k| h[k] = [] }) {|h, w| (h[w.size] ||= []) << w; h }
22
+ end
23
+ end
24
+
25
+ def self.first_names(options)
26
+ case options[:gender].to_s
27
+ when /^male/i
28
+ male_first_names(options)
29
+ when /^female/i
30
+ female_first_names(options)
31
+ else
32
+ [male_first_names(options), female_first_names(options)].pick_rand_value
33
+ end
34
+ end
35
+ end