shiritori 0.1.3 → 0.1.6
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 +4 -4
- data/.gitignore +1 -0
- data/.travis.yml +7 -0
- data/Gemfile +3 -0
- data/README.md +19 -2
- data/bin/shiritori +1 -1
- data/lib/shiritori/cli.rb +17 -0
- data/lib/shiritori/convert.rb +6 -5
- data/lib/shiritori/error.rb +8 -3
- data/lib/shiritori/search_method.rb +6 -8
- data/lib/shiritori/shiritori.rb +102 -50
- data/lib/shiritori/version.rb +1 -1
- data/lib/shiritori/view.rb +40 -20
- data/lib/shiritori/yaml/array.yaml +184 -0
- data/lib/shiritori/yaml/basic_object.yaml +11 -0
- data/lib/shiritori/yaml/bignum.yaml +35 -0
- data/lib/shiritori/yaml/binding.yaml +7 -0
- data/lib/shiritori/yaml/condition_variable.yaml +7 -0
- data/lib/shiritori/yaml/encoding.yaml +10 -0
- data/lib/shiritori/yaml/enumerator.yaml +13 -0
- data/lib/shiritori/yaml/exception.yaml +10 -0
- data/lib/shiritori/yaml/false.yaml +8 -0
- data/lib/shiritori/yaml/file.yaml +73 -0
- data/lib/shiritori/yaml/fixnum.yaml +37 -0
- data/lib/shiritori/yaml/match_data.yaml +22 -0
- data/lib/shiritori/yaml/method.yaml +19 -0
- data/lib/shiritori/yaml/module.yaml +40 -0
- data/lib/shiritori/yaml/mutex.yaml +11 -0
- data/lib/shiritori/yaml/nil.yaml +14 -0
- data/lib/shiritori/yaml/object.yaml +61 -0
- data/lib/shiritori/yaml/proc.yaml +17 -0
- data/lib/shiritori/yaml/queue.yaml +15 -0
- data/lib/shiritori/yaml/random.yaml +6 -0
- data/lib/shiritori/yaml/range.yaml +22 -0
- data/lib/shiritori/yaml/regexp.yaml +24 -0
- data/lib/shiritori/yaml/sized_queue.yaml +11 -0
- data/lib/shiritori/yaml/string.yaml +87 -0
- data/lib/shiritori/yaml/symbol.yaml +26 -0
- data/lib/shiritori/yaml/thread.yaml +43 -0
- data/lib/shiritori/yaml/true.yaml +8 -0
- data/lib/shiritori/yaml/unbound_method.yaml +15 -0
- data/lib/shiritori.rb +7 -3
- data/shiritori.gemspec +2 -0
- data/spec/shiritori/bignum_method_spec.rb +4 -1
- data/spec/shiritori/enumerator_method_spec.rb +9 -0
- data/spec/shiritori/fixnum_method_spec.rb +3 -1
- data/spec/shiritori/shiritori_spec.rb +49 -0
- data/spec/shiritori/string_method_spec.rb +4 -2
- data/spec/spec_helper.rb +16 -13
- metadata +49 -5
- data/lib/shiritori/command.rb +0 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 210de60ebae0c8b80e6f0c8195f12ef3a6339c25
|
4
|
+
data.tar.gz: 38148907162c13381d5394651a52571af46967d3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 215cf4485ece83ae8b88ccc5065eb5797618368f77fe309636114b2a66ee4d209a554bb76dedaa9c6bde795785b8d09781585b9733be98cfcf565c446aa1582b
|
7
|
+
data.tar.gz: 21254ab6c0fe3b04dae92283a21c92e878a6a5833612c84a31a7d851c3e27f114f53b98398c0715484fa37e6998db28d0af79647360a5661048acf3cc663a916
|
data/.gitignore
CHANGED
data/.travis.yml
ADDED
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -1,3 +1,7 @@
|
|
1
|
+
[](https://travis-ci.org/siman-man/shiritori)
|
2
|
+
[](https://codeclimate.com/github/siman-man/shiritori)
|
3
|
+
[](https://coveralls.io/r/siman-man/shiritori)
|
4
|
+
|
1
5
|
# Shiritori
|
2
6
|
|
3
7
|
Let's try to create too long method chain!
|
@@ -24,6 +28,20 @@ Let's start creation long method chain.
|
|
24
28
|
|
25
29
|
- block syntax can use only '{}', not use 'do - end' syntax.
|
26
30
|
- if you want to pass arguments, please enclosed '()'.
|
31
|
+
|
32
|
+
bad
|
33
|
+
|
34
|
+
```
|
35
|
+
Please input next method > +5
|
36
|
+
Exec command 3.+5
|
37
|
+
```
|
38
|
+
|
39
|
+
good
|
40
|
+
|
41
|
+
```
|
42
|
+
Please input next method > +(5)
|
43
|
+
Exec command 3.+(5)
|
44
|
+
```
|
27
45
|
|
28
46
|
## Usage
|
29
47
|
|
@@ -76,10 +94,9 @@ Exec command ["H", "e", "l", "l", "o"].first
|
|
76
94
|
Please input next method >
|
77
95
|
```
|
78
96
|
|
79
|
-
|
80
97
|
## Contributing
|
81
98
|
|
82
|
-
1. Fork it ( https://github.com/
|
99
|
+
1. Fork it ( https://github.com/siman-man/shiritori/fork )
|
83
100
|
2. Create your feature branch (`git checkout -b my-new-feature`)
|
84
101
|
3. Commit your changes (`git commit -am 'Add some feature'`)
|
85
102
|
4. Push to the branch (`git push origin my-new-feature`)
|
data/bin/shiritori
CHANGED
@@ -0,0 +1,17 @@
|
|
1
|
+
module Shiritori
|
2
|
+
class CLI < Thor
|
3
|
+
GAME_MODE = [:easy, :normal]
|
4
|
+
|
5
|
+
desc "start", "Start GAME!"
|
6
|
+
option :mode
|
7
|
+
def start
|
8
|
+
mode = (options[:mode])? options[:mode].to_sym : :normal
|
9
|
+
|
10
|
+
if GAME_MODE.include?(mode)
|
11
|
+
Main.new.start(mode: mode)
|
12
|
+
else
|
13
|
+
puts "Mode is not only easy or normal."
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
data/lib/shiritori/convert.rb
CHANGED
@@ -1,19 +1,20 @@
|
|
1
1
|
class String
|
2
|
-
BLANK_PATTERN =
|
2
|
+
BLANK_PATTERN = /^\s*$/
|
3
3
|
|
4
4
|
def blank?
|
5
|
-
|
5
|
+
self.size == 0 or self == BLANK_PATTERN
|
6
6
|
end
|
7
7
|
end
|
8
8
|
|
9
9
|
class NilClass
|
10
10
|
def to_ss
|
11
|
-
|
11
|
+
'nil'
|
12
12
|
end
|
13
13
|
end
|
14
14
|
|
15
15
|
module Kernel
|
16
16
|
undef_method :exit
|
17
|
+
undef_method :abort
|
17
18
|
end
|
18
19
|
|
19
20
|
class Object
|
@@ -41,5 +42,5 @@ class BasicObject
|
|
41
42
|
::Kernel.eval(str, __binding__)
|
42
43
|
end
|
43
44
|
|
44
|
-
|
45
|
-
end
|
45
|
+
alias_method :to_s, :to_ss
|
46
|
+
end
|
data/lib/shiritori/error.rb
CHANGED
@@ -1,10 +1,15 @@
|
|
1
1
|
module Shiritori
|
2
|
-
class ShiritoriError < Exception
|
3
|
-
end
|
2
|
+
class ShiritoriError < Exception; end
|
4
3
|
|
5
4
|
class UseSameMethodError < ShiritoriError
|
6
5
|
def message
|
7
|
-
|
6
|
+
%q(Can't use same method.)
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
class UndefinedObjectError < ShiritoriError
|
11
|
+
def message
|
12
|
+
'Undefined Object'
|
8
13
|
end
|
9
14
|
end
|
10
15
|
end
|
@@ -3,7 +3,7 @@ module Shiritori
|
|
3
3
|
UNUSE_METHOD = [:exit]
|
4
4
|
|
5
5
|
def get_all_method
|
6
|
-
@check_list =
|
6
|
+
@check_list = {}
|
7
7
|
@method_list = []
|
8
8
|
|
9
9
|
scan_method
|
@@ -12,18 +12,16 @@ module Shiritori
|
|
12
12
|
end
|
13
13
|
|
14
14
|
def singleton(klass)
|
15
|
-
class << klass; self end
|
16
|
-
end
|
15
|
+
class << klass; self end
|
16
|
+
end
|
17
17
|
|
18
18
|
def scan_method(klass = BasicObject)
|
19
19
|
@check_list[klass] = true
|
20
20
|
@method_list |= klass.instance_methods
|
21
21
|
|
22
|
-
ObjectSpace.each_object(singleton(klass)) do |subclass|
|
23
|
-
if klass != subclass
|
24
|
-
scan_method(subclass) unless @check_list[subclass]
|
25
|
-
end
|
22
|
+
ObjectSpace.each_object(singleton(klass)) do |subclass|
|
23
|
+
scan_method(subclass) if klass != subclass && @check_list[subclass].nil?
|
26
24
|
end
|
27
25
|
end
|
28
26
|
end
|
29
|
-
end
|
27
|
+
end
|
data/lib/shiritori/shiritori.rb
CHANGED
@@ -3,58 +3,82 @@ require 'readline'
|
|
3
3
|
|
4
4
|
module Shiritori
|
5
5
|
class Main
|
6
|
-
attr_reader :current_object, :chain_count
|
6
|
+
attr_reader :current_object, :chain_count, :error_count, :mode, :use_method_list
|
7
7
|
include SearchMethod
|
8
8
|
include View
|
9
9
|
|
10
|
+
# ColorCode
|
10
11
|
RED = 31
|
11
12
|
GREEN = 32
|
12
13
|
|
13
14
|
EXIT_PATTERN = /\A(exit|quit)\Z/.freeze
|
15
|
+
HELP_PATTERN = /\A(help|h)\Z/.freeze
|
14
16
|
METHOD_PATTERN = /[\w|\?|\>|\<|\=|\!|\[|\[|\]|\*|\/|\+|\-|\^|\~|\@|\%|\&|]+/.freeze
|
15
17
|
|
16
|
-
|
17
|
-
|
18
|
-
|
18
|
+
# timelimit is 1 second
|
19
|
+
TIME_LIMIT = 1
|
20
|
+
|
21
|
+
def start(mode: :normal)
|
22
|
+
welcome_message
|
23
|
+
|
24
|
+
begin
|
25
|
+
init(mode)
|
26
|
+
run
|
27
|
+
rescue Exception => ex
|
28
|
+
puts ex.message
|
29
|
+
ensure
|
30
|
+
show_result
|
31
|
+
end
|
19
32
|
end
|
20
33
|
|
21
|
-
def update(
|
22
|
-
if
|
23
|
-
@all_method.delete(
|
24
|
-
@
|
34
|
+
def update(action: nil, object: nil)
|
35
|
+
if action
|
36
|
+
@all_method.delete(action)
|
37
|
+
@use_method_list << action
|
38
|
+
@current_object = object
|
25
39
|
@chain_count += 1
|
26
40
|
end
|
27
41
|
|
28
42
|
begin
|
29
|
-
@current_class =
|
30
|
-
rescue
|
31
|
-
@current_class =
|
43
|
+
@current_class = current_object.class
|
44
|
+
rescue NoMethodError => ex
|
45
|
+
@current_class = 'Undefined'
|
32
46
|
end
|
33
47
|
|
48
|
+
show_status(@current_chain, @current_object, @current_class, @chain_count)
|
34
49
|
@success = true
|
35
50
|
end
|
36
51
|
|
37
|
-
def init
|
52
|
+
def init(mode)
|
38
53
|
@all_method = get_all_method
|
39
|
-
@current_object = nil
|
40
54
|
@current_class = Object
|
41
55
|
@current_chain = []
|
56
|
+
@use_method_list = []
|
42
57
|
@chain_count = 0
|
58
|
+
@error_count = 0
|
43
59
|
@success = false
|
44
|
-
|
60
|
+
@mode = mode
|
45
61
|
|
46
|
-
|
62
|
+
require 'timeout'
|
63
|
+
require 'ripper'
|
47
64
|
|
65
|
+
loop do
|
48
66
|
command = get_command
|
67
|
+
redo if command.empty?
|
68
|
+
|
69
|
+
begin
|
70
|
+
Thread.new do
|
71
|
+
timeout(TIME_LIMIT) do
|
72
|
+
@current_object = eval(command.chomp)
|
73
|
+
end
|
74
|
+
end.join
|
49
75
|
|
50
|
-
begin
|
51
|
-
@current_object = eval(command.chomp)
|
52
76
|
@current_chain << @current_object.to_ss
|
53
77
|
@success = true
|
54
78
|
break
|
55
79
|
rescue Exception => ex
|
56
|
-
|
57
|
-
$error_message
|
80
|
+
$error_message = ex.message
|
81
|
+
puts "\e[#{RED}m#{$error_message}\e[m"
|
58
82
|
redo
|
59
83
|
end
|
60
84
|
end
|
@@ -62,11 +86,18 @@ module Shiritori
|
|
62
86
|
update
|
63
87
|
end
|
64
88
|
|
65
|
-
def
|
66
|
-
@success
|
89
|
+
def check_success
|
90
|
+
if @success
|
91
|
+
puts "\e[#{GREEN}mSuccess!\e[m"
|
92
|
+
@success = false
|
93
|
+
else
|
94
|
+
puts "\e[#{RED}mFailed! : #{$error_message}\e[m"
|
95
|
+
end
|
96
|
+
|
97
|
+
new_line
|
67
98
|
end
|
68
99
|
|
69
|
-
def get_command(message =
|
100
|
+
def get_command(message = 'Please input first object > ')
|
70
101
|
if Shiritori.env == :development
|
71
102
|
print message
|
72
103
|
$stdin.gets
|
@@ -76,66 +107,87 @@ module Shiritori
|
|
76
107
|
end
|
77
108
|
|
78
109
|
def run
|
79
|
-
|
80
110
|
loop do
|
81
|
-
|
82
|
-
|
83
|
-
if success?
|
84
|
-
puts "\e[#{GREEN}mSuccess!\e[m"
|
85
|
-
@success = false
|
86
|
-
else
|
87
|
-
puts "\e[#{RED}mFailed! : #{$error_message}\e[m"
|
88
|
-
end
|
89
|
-
|
90
|
-
new_line
|
111
|
+
command = get_command('Please input next method > ')
|
91
112
|
|
92
|
-
|
93
|
-
|
94
|
-
break if command.nil?
|
113
|
+
break if command.nil?
|
95
114
|
redo if command.blank?
|
96
115
|
|
97
|
-
command = command.chomp.sub(/^\./,
|
98
|
-
|
99
|
-
puts "Exec command #{[@current_object.to_ss, command].join('.')}"
|
116
|
+
command = command.chomp.sub(/^\./, '')
|
100
117
|
|
101
118
|
begin
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
119
|
+
result = exec_method_chain(command, current_object)
|
120
|
+
|
121
|
+
redo unless result
|
122
|
+
|
123
|
+
action = result.first
|
124
|
+
object = result.last
|
125
|
+
|
126
|
+
if action == :help
|
127
|
+
help_me(current_object)
|
128
|
+
redo
|
129
|
+
elsif action == :exit
|
130
|
+
break
|
131
|
+
elsif @all_method.include?(action)
|
132
|
+
puts "Exec command #{[@current_object.to_ss, command].join('.')}"
|
133
|
+
@current_chain << command
|
134
|
+
update(action: action, object: object)
|
135
|
+
else
|
136
|
+
$error_message = "#{action} is already used."
|
137
|
+
raise Shiritori::UseSameMethodError
|
111
138
|
end
|
112
139
|
rescue Exception => ex
|
140
|
+
@error_count += 1
|
113
141
|
puts "\e[#{RED}m#{ex.message}\e[m"
|
114
142
|
end
|
143
|
+
|
144
|
+
check_success
|
115
145
|
end
|
116
146
|
end
|
117
147
|
|
118
148
|
def exec_method_chain(command, object)
|
119
149
|
method_name = command.scan(METHOD_PATTERN).first.to_sym
|
120
|
-
result = [
|
150
|
+
result = [method_name]
|
121
151
|
|
122
152
|
case command
|
123
153
|
when EXIT_PATTERN
|
124
154
|
return [:exit]
|
155
|
+
when HELP_PATTERN
|
156
|
+
return [:help]
|
125
157
|
else
|
126
158
|
begin
|
127
159
|
Thread.new do
|
128
160
|
raise NoMethodError unless object.respond_to?(method_name)
|
129
161
|
|
130
|
-
|
162
|
+
timeout(TIME_LIMIT) do
|
163
|
+
result << eval('object.' + command)
|
164
|
+
end
|
131
165
|
end.join
|
132
166
|
rescue Exception => ex
|
167
|
+
@error_count += 1
|
133
168
|
$error_message = ex.message
|
169
|
+
failed_message("Exec command #{[@current_object.to_ss, command].join('.')}")
|
170
|
+
failed_message("Failed! : #{$error_message}")
|
134
171
|
return false
|
135
172
|
end
|
136
173
|
end
|
137
174
|
|
138
175
|
result
|
139
176
|
end
|
177
|
+
|
178
|
+
private
|
179
|
+
def help_me(current_object)
|
180
|
+
can_use_methods = current_object.methods - use_method_list
|
181
|
+
|
182
|
+
new_line
|
183
|
+
|
184
|
+
if mode == :easy
|
185
|
+
puts "You can use methods: #{can_use_methods.sample(5).inspect}"
|
186
|
+
else
|
187
|
+
puts "\e[#{RED}mOh.. Sory, help command is only exist easy mode.\e[m"
|
188
|
+
end
|
189
|
+
|
190
|
+
new_line
|
191
|
+
end
|
140
192
|
end
|
141
193
|
end
|
data/lib/shiritori/version.rb
CHANGED
data/lib/shiritori/view.rb
CHANGED
@@ -2,37 +2,57 @@ module Shiritori
|
|
2
2
|
module View
|
3
3
|
PADDING = 2
|
4
4
|
|
5
|
+
# ColorCode
|
6
|
+
RED = 31
|
7
|
+
GREEN = 32
|
8
|
+
|
5
9
|
def new_line(num = 0)
|
6
|
-
|
10
|
+
puts "\n" * num
|
7
11
|
end
|
8
12
|
|
9
13
|
def welcome_message
|
14
|
+
width = 50
|
15
|
+
puts "+#{'-' * width}+"
|
16
|
+
puts "|#{' ' * width}|"
|
17
|
+
puts "|#{'Welcome to the Shiritori!'.center(width)}|"
|
18
|
+
puts "|#{' ' * width}|"
|
19
|
+
puts "+#{'-' * width}+"
|
20
|
+
end
|
21
|
+
|
22
|
+
def failed_message(message)
|
23
|
+
puts "\e[#{RED}m#{message}\e[m"
|
10
24
|
end
|
11
25
|
|
12
|
-
def
|
26
|
+
def input_message
|
27
|
+
end
|
28
|
+
|
29
|
+
def show_status(current_chain, current_object, current_class, chain_count)
|
13
30
|
new_line
|
14
|
-
chain = "#{
|
15
|
-
chain_size = [chain.size+PADDING, 22].max
|
31
|
+
chain = "#{current_chain.join('.')}"
|
32
|
+
chain_size = [chain.size + PADDING, 22].max
|
16
33
|
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
34
|
+
puts "+#{'-' * chain_size}+"
|
35
|
+
puts "|#{'Current method chain'.center(chain_size)}|"
|
36
|
+
puts "+#{'-' * chain_size}+"
|
37
|
+
puts "|#{current_chain.join('.').center(chain_size)}|"
|
38
|
+
puts "+#{'-' * chain_size}+"
|
22
39
|
|
23
|
-
cls = "#{
|
24
|
-
obj = "#{
|
25
|
-
cls_size = ["#{
|
26
|
-
|
40
|
+
cls = "#{current_class}"
|
41
|
+
obj = "#{current_object.to_ss}"
|
42
|
+
cls_size = ["#{current_class}".size, 13].max + PADDING
|
43
|
+
cnt_size = 11 + PADDING
|
44
|
+
obj_size = ["#{current_object}".size, 14].max + PADDING
|
27
45
|
|
28
46
|
new_line
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
47
|
+
puts "+#{'-' * (cls_size)}+#{'-' * cnt_size}+#{'-' * (obj_size)}+"
|
48
|
+
puts "|#{'Current Class'.center(cls_size)}|#{'Chain Count'.center(cnt_size)}|#{'Current Object'.center(obj_size)}|"
|
49
|
+
puts "+#{'-' * (cls_size)}+#{'-' * cnt_size}+#{'-' * (obj_size)}+"
|
50
|
+
puts "|#{cls.center(cls_size)}|#{chain_count.to_s.center(cnt_size)}|#{obj.center(obj_size)}|"
|
51
|
+
puts "+#{'-' * (cls_size)}+#{'-' * cnt_size}+#{'-' * (obj_size)}+"
|
34
52
|
new_line
|
35
|
-
|
53
|
+
end
|
54
|
+
|
55
|
+
def show_result
|
36
56
|
end
|
37
57
|
end
|
38
|
-
end
|
58
|
+
end
|