shiritori 0.1.3 → 0.1.6
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
+
[![Build Status](https://travis-ci.org/siman-man/shiritori.svg?branch=master)](https://travis-ci.org/siman-man/shiritori)
|
2
|
+
[![Code Climate](https://codeclimate.com/github/siman-man/shiritori.png)](https://codeclimate.com/github/siman-man/shiritori)
|
3
|
+
[![Coverage Status](https://coveralls.io/repos/siman-man/shiritori/badge.png)](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
|