gimei 0.1.0 → 0.5.1

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.
@@ -1,141 +1,68 @@
1
- require "gimei/version"
1
+ require 'forwardable'
2
2
  require 'yaml'
3
+ require 'gimei/version'
4
+ require 'gimei/name'
5
+ require 'gimei/address'
6
+ require 'gimei/unique_generator'
7
+ require 'gimei/config'
3
8
 
4
9
  class Gimei
10
+ extend Forwardable
11
+
5
12
  NAMES = YAML.load_file(File.expand_path(File.join('..', 'data', 'names.yml'), __FILE__))
6
- GENDER = [:male, :female].freeze
13
+ ADDRESSES = YAML.load_file(File.expand_path(File.join('..', 'data', 'addresses.yml'), __FILE__))
14
+ GENDERS = [:male, :female].freeze
7
15
 
8
- class << self
9
- def male
10
- new(:male)
11
- end
16
+ def_delegators :@name, :gender, :kanji, :hiragana, :katakana, :first, :last, :male?, :female?, :romaji
17
+ def_delegators :@address, :prefecture, :city, :town
18
+ alias_method :to_s, :kanji
12
19
 
13
- def female
14
- new(:female)
15
- end
20
+ attr_reader :name, :address
16
21
 
17
- def kanji
18
- name = new
19
- "#{name.last.kanji} #{name.first.kanji}"
20
- end
22
+ class << self
23
+ extend Forwardable
21
24
 
22
- def hiragana
23
- name = new
24
- "#{name.last.hiragana} #{name.first.hiragana}"
25
- end
25
+ def_delegators Gimei::Name, :male, :female
26
+ def_delegators :address, :prefecture, :city, :town
26
27
 
27
- def katakana
28
- name = new
29
- "#{name.last.katakana} #{name.first.katakana}"
28
+ def name(gender = nil)
29
+ Name.new(gender)
30
30
  end
31
31
 
32
- def first
33
- new.first
32
+ %i[kanji hiragana katakana romaji first last].each do |method_name|
33
+ define_method(method_name) do |gender = nil|
34
+ name(gender).public_send(method_name)
35
+ end
34
36
  end
35
37
 
36
- def last
37
- new.last
38
+ def address
39
+ Address.new
38
40
  end
39
- end
40
-
41
- def initialize(gender = nil)
42
- @gender = gender || GENDER.sample
43
- @first = First.new @gender
44
- @last = Last.new
45
- end
46
-
47
- def kanji
48
- "#{last.kanji} #{first.kanji}"
49
- end
50
-
51
- def hiragana
52
- "#{last.hiragana} #{first.hiragana}"
53
- end
54
-
55
- def katakana
56
- "#{last.katakana} #{first.katakana}"
57
- end
58
-
59
- def to_s
60
- kanji
61
- end
62
-
63
- def first
64
- @first
65
- end
66
-
67
- def last
68
- @last
69
- end
70
41
 
71
- def male?
72
- @gender == :male
73
- end
42
+ def unique(max_retries = 10_000)
43
+ return @unique if defined? @unique
74
44
 
75
- def female?
76
- @gender == :female
77
- end
45
+ @unique = UniqueGenerator.new(self, max_retries)
78
46
 
79
- class First
80
- class << self
81
- def male
82
- new(:male)
47
+ %i[name last first hiragana katakana romaji address prefecture city town].each do |method_name|
48
+ @unique.define_unique_method(method_name)
83
49
  end
84
50
 
85
- def female
86
- new(:female)
51
+ %i[male female kanji].each do |method_name|
52
+ @unique.define_unique_method(method_name, :name)
87
53
  end
88
- end
89
-
90
- def initialize(gender = nil)
91
- @gender = gender || GENDER.sample
92
- @name = NAMES['first_name'][@gender.to_s].sample
93
- end
94
-
95
- def male?
96
- @gender == :male
97
- end
98
-
99
- def female?
100
- @gender == :female
101
- end
102
-
103
- def kanji
104
- @name[0]
105
- end
106
54
 
107
- def hiragana
108
- @name[1]
55
+ @unique
109
56
  end
110
57
 
111
- def katakana
112
- @name[2]
113
- end
114
-
115
- def to_s
116
- kanji
58
+ def config
59
+ @config ||= Config.new
117
60
  end
118
61
  end
119
62
 
120
- class Last
121
- def initialize
122
- @name = NAMES['last_name'].sample
123
- end
124
-
125
- def kanji
126
- @name[0]
127
- end
128
63
 
129
- def hiragana
130
- @name[1]
131
- end
132
-
133
- def katakana
134
- @name[2]
135
- end
136
-
137
- def to_s
138
- kanji
139
- end
64
+ def initialize(gender = nil)
65
+ @name = Name.new(gender)
66
+ @address = Address.new
140
67
  end
141
68
  end
@@ -0,0 +1,99 @@
1
+ class Gimei::Address
2
+ attr_reader :prefecture, :city, :town
3
+
4
+ def initialize
5
+ @prefecture = Prefecture.new
6
+ @city = City.new
7
+ @town = Town.new
8
+ end
9
+
10
+ def kanji
11
+ "#{prefecture.kanji}#{city.kanji}#{town.kanji}"
12
+ end
13
+
14
+ def hiragana
15
+ "#{prefecture.hiragana}#{city.hiragana}#{town.hiragana}"
16
+ end
17
+
18
+ def katakana
19
+ "#{prefecture.katakana}#{city.katakana}#{town.katakana}"
20
+ end
21
+
22
+ def romaji
23
+ "#{prefecture.romaji} #{city.romaji} #{town.romaji}"
24
+ end
25
+
26
+ alias_method :to_s, :kanji
27
+
28
+ class Prefecture
29
+ def kanji
30
+ @prefectures[0]
31
+ end
32
+
33
+ def hiragana
34
+ @prefectures[1]
35
+ end
36
+
37
+ def katakana
38
+ @prefectures[2]
39
+ end
40
+
41
+ def romaji
42
+ Romaji.kana2romaji(hiragana).capitalize
43
+ end
44
+
45
+ def initialize
46
+ @prefectures = Gimei::ADDRESSES['addresses']['prefecture'].sample(random: Gimei.config.rng)
47
+ end
48
+
49
+ alias_method :to_s, :kanji
50
+ end
51
+
52
+ class City
53
+ def kanji
54
+ @cities[0]
55
+ end
56
+
57
+ def hiragana
58
+ @cities[1]
59
+ end
60
+
61
+ def katakana
62
+ @cities[2]
63
+ end
64
+
65
+ def romaji
66
+ Romaji.kana2romaji(hiragana).capitalize
67
+ end
68
+
69
+ def initialize
70
+ @cities = Gimei::ADDRESSES['addresses']['city'].sample(random: Gimei.config.rng)
71
+ end
72
+
73
+ alias_method :to_s, :kanji
74
+ end
75
+
76
+ class Town
77
+ def kanji
78
+ @towns[0]
79
+ end
80
+
81
+ def hiragana
82
+ @towns[1]
83
+ end
84
+
85
+ def katakana
86
+ @towns[2]
87
+ end
88
+
89
+ def romaji
90
+ Romaji.kana2romaji(hiragana).capitalize
91
+ end
92
+
93
+ def initialize
94
+ @towns = Gimei::ADDRESSES['addresses']['town'].sample(random: Gimei.config.rng)
95
+ end
96
+
97
+ alias_method :to_s, :kanji
98
+ end
99
+ end
@@ -0,0 +1,9 @@
1
+ class Gimei
2
+ class Config
3
+ attr_accessor :rng
4
+
5
+ def initialize(rng: Random.new)
6
+ @rng = rng
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,116 @@
1
+ require 'romaji'
2
+
3
+ class Gimei::Name
4
+ attr_reader :first, :last, :gender
5
+
6
+ class << self
7
+ extend Forwardable
8
+
9
+ def male
10
+ new(:male)
11
+ end
12
+
13
+ def female
14
+ new(:female)
15
+ end
16
+
17
+ %i[kanji hiragana katakana romaji first last].each do |method_name|
18
+ define_method(method_name) do |gender = nil|
19
+ new(gender).public_send(method_name)
20
+ end
21
+ end
22
+ end
23
+
24
+ def initialize(gender = nil)
25
+ @gender = gender || Gimei::GENDERS.sample(random: Gimei.config.rng)
26
+ @first = First.new @gender
27
+ @last = Last.new
28
+ end
29
+
30
+ def kanji
31
+ "#{last.kanji} #{first.kanji}"
32
+ end
33
+
34
+ def hiragana
35
+ "#{last.hiragana} #{first.hiragana}"
36
+ end
37
+
38
+ def katakana
39
+ "#{last.katakana} #{first.katakana}"
40
+ end
41
+
42
+ def romaji
43
+ "#{first.romaji} #{last.romaji}"
44
+ end
45
+
46
+ def male?
47
+ @gender == :male
48
+ end
49
+
50
+ def female?
51
+ @gender == :female
52
+ end
53
+
54
+ alias_method :to_s, :kanji
55
+
56
+ class First
57
+ class << self
58
+ def male
59
+ new(:male)
60
+ end
61
+
62
+ def female
63
+ new(:female)
64
+ end
65
+ end
66
+
67
+ extend Forwardable
68
+ def_delegators :@name, :kanji, :hiragana, :katakana, :to_s, :romaji
69
+
70
+ def initialize(gender = nil)
71
+ @gender = gender || Gimei::GENDERS.sample(random: Gimei.config.rng)
72
+ @name = NameWord.new(Gimei::NAMES['first_name'][@gender.to_s].sample(random: Gimei.config.rng))
73
+ end
74
+
75
+ def male?
76
+ @gender == :male
77
+ end
78
+
79
+ def female?
80
+ @gender == :female
81
+ end
82
+ end
83
+
84
+ class Last
85
+ extend Forwardable
86
+ def_delegators :@name, :kanji, :hiragana, :katakana, :to_s, :romaji
87
+
88
+ def initialize
89
+ @name = NameWord.new(Gimei::NAMES['last_name'].sample(random: Gimei.config.rng))
90
+ end
91
+ end
92
+
93
+ class NameWord
94
+ def initialize(name)
95
+ @name = name
96
+ end
97
+
98
+ def kanji
99
+ @name[0]
100
+ end
101
+
102
+ def hiragana
103
+ @name[1]
104
+ end
105
+
106
+ def katakana
107
+ @name[2]
108
+ end
109
+
110
+ def romaji
111
+ Romaji.kana2romaji(hiragana).capitalize
112
+ end
113
+
114
+ alias_method :to_s, :kanji
115
+ end
116
+ end
@@ -0,0 +1,47 @@
1
+ class Gimei
2
+ class RetryLimitExceeded < StandardError; end
3
+
4
+ class UniqueGenerator
5
+ class << self
6
+ def previous_results
7
+ @previous_results ||= Hash.new { |hash, key| hash[key] = Set.new }
8
+ end
9
+ end
10
+
11
+ def initialize(klass, max_retries)
12
+ @klass = klass
13
+ @max_retries = max_retries
14
+ end
15
+
16
+ def previous_results
17
+ self.class.previous_results
18
+ end
19
+
20
+ def clear(key = nil)
21
+ if key
22
+ previous_results[key.to_sym].clear
23
+ else
24
+ previous_results.clear
25
+ end
26
+ end
27
+
28
+ def define_unique_method(method_name, previous_result_key = method_name)
29
+ define_singleton_method method_name do |*args|
30
+ max_retries.times do
31
+ result = klass.public_send(method_name, *args)
32
+
33
+ next if previous_results[previous_result_key].include?(result.to_s)
34
+
35
+ previous_results[previous_result_key] << result.to_s
36
+ return result
37
+ end
38
+
39
+ raise RetryLimitExceeded, "Retry limit exceeded for #{method_name}"
40
+ end
41
+ end
42
+
43
+ private
44
+
45
+ attr_reader :klass, :max_retries
46
+ end
47
+ end