shiritori 0.1.3 → 0.1.6

Sign up to get free protection for your applications and to get access to all the features.
Files changed (51) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/.travis.yml +7 -0
  4. data/Gemfile +3 -0
  5. data/README.md +19 -2
  6. data/bin/shiritori +1 -1
  7. data/lib/shiritori/cli.rb +17 -0
  8. data/lib/shiritori/convert.rb +6 -5
  9. data/lib/shiritori/error.rb +8 -3
  10. data/lib/shiritori/search_method.rb +6 -8
  11. data/lib/shiritori/shiritori.rb +102 -50
  12. data/lib/shiritori/version.rb +1 -1
  13. data/lib/shiritori/view.rb +40 -20
  14. data/lib/shiritori/yaml/array.yaml +184 -0
  15. data/lib/shiritori/yaml/basic_object.yaml +11 -0
  16. data/lib/shiritori/yaml/bignum.yaml +35 -0
  17. data/lib/shiritori/yaml/binding.yaml +7 -0
  18. data/lib/shiritori/yaml/condition_variable.yaml +7 -0
  19. data/lib/shiritori/yaml/encoding.yaml +10 -0
  20. data/lib/shiritori/yaml/enumerator.yaml +13 -0
  21. data/lib/shiritori/yaml/exception.yaml +10 -0
  22. data/lib/shiritori/yaml/false.yaml +8 -0
  23. data/lib/shiritori/yaml/file.yaml +73 -0
  24. data/lib/shiritori/yaml/fixnum.yaml +37 -0
  25. data/lib/shiritori/yaml/match_data.yaml +22 -0
  26. data/lib/shiritori/yaml/method.yaml +19 -0
  27. data/lib/shiritori/yaml/module.yaml +40 -0
  28. data/lib/shiritori/yaml/mutex.yaml +11 -0
  29. data/lib/shiritori/yaml/nil.yaml +14 -0
  30. data/lib/shiritori/yaml/object.yaml +61 -0
  31. data/lib/shiritori/yaml/proc.yaml +17 -0
  32. data/lib/shiritori/yaml/queue.yaml +15 -0
  33. data/lib/shiritori/yaml/random.yaml +6 -0
  34. data/lib/shiritori/yaml/range.yaml +22 -0
  35. data/lib/shiritori/yaml/regexp.yaml +24 -0
  36. data/lib/shiritori/yaml/sized_queue.yaml +11 -0
  37. data/lib/shiritori/yaml/string.yaml +87 -0
  38. data/lib/shiritori/yaml/symbol.yaml +26 -0
  39. data/lib/shiritori/yaml/thread.yaml +43 -0
  40. data/lib/shiritori/yaml/true.yaml +8 -0
  41. data/lib/shiritori/yaml/unbound_method.yaml +15 -0
  42. data/lib/shiritori.rb +7 -3
  43. data/shiritori.gemspec +2 -0
  44. data/spec/shiritori/bignum_method_spec.rb +4 -1
  45. data/spec/shiritori/enumerator_method_spec.rb +9 -0
  46. data/spec/shiritori/fixnum_method_spec.rb +3 -1
  47. data/spec/shiritori/shiritori_spec.rb +49 -0
  48. data/spec/shiritori/string_method_spec.rb +4 -2
  49. data/spec/spec_helper.rb +16 -13
  50. metadata +49 -5
  51. data/lib/shiritori/command.rb +0 -6
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 17184fcd8187e6c1a64d91a3bbc82d8476c99775
4
- data.tar.gz: c1c6cf6c837cae1c0903d92a0068772b9ae83aee
3
+ metadata.gz: 210de60ebae0c8b80e6f0c8195f12ef3a6339c25
4
+ data.tar.gz: 38148907162c13381d5394651a52571af46967d3
5
5
  SHA512:
6
- metadata.gz: 2d4d8a19cd26558424eafb426cd587dc89b5ceed620b38b0313d38524d3e80345deb2052a232430b342b7b9ec88931e3a89c3fe8e33ee74d6417c9a00296e84f
7
- data.tar.gz: b81c85d900714949f64cc1f297aaa5e4e07b34fb6a650bcc072e0dcb90589e2001506f9c3b54397f274791f4a147cdb1707eb3245f7e3395e159fa5509db1998
6
+ metadata.gz: 215cf4485ece83ae8b88ccc5065eb5797618368f77fe309636114b2a66ee4d209a554bb76dedaa9c6bde795785b8d09781585b9733be98cfcf565c446aa1582b
7
+ data.tar.gz: 21254ab6c0fe3b04dae92283a21c92e878a6a5833612c84a31a7d851c3e27f114f53b98398c0715484fa37e6998db28d0af79647360a5661048acf3cc663a916
data/.gitignore CHANGED
@@ -7,6 +7,7 @@ Gemfile.lock
7
7
  InstalledFiles
8
8
  _yardoc
9
9
  coverage
10
+ .coveralls.yml
10
11
  doc/
11
12
  lib/bundler/man
12
13
  pkg
data/.travis.yml ADDED
@@ -0,0 +1,7 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.0.0
4
+ - 2.1
5
+ - 2.2
6
+
7
+ script: bundle exec rspec spec
data/Gemfile CHANGED
@@ -2,3 +2,6 @@ source 'https://rubygems.org'
2
2
 
3
3
  # Specify your gem's dependencies in shiritori.gemspec
4
4
  gemspec
5
+
6
+ gem 'coveralls', require: false
7
+ gem 'thor'
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/[my-github-username]/shiritori/fork )
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
@@ -2,4 +2,4 @@
2
2
 
3
3
  require 'shiritori'
4
4
 
5
- Shiritori::Main.new.start(ARGV)
5
+ Shiritori::CLI.start(ARGV)
@@ -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
@@ -1,19 +1,20 @@
1
1
  class String
2
- BLANK_PATTERN = /\A\s*\z/
2
+ BLANK_PATTERN = /^\s*$/
3
3
 
4
4
  def blank?
5
- BLANK_PATTERN === self
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
- "nil"
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
- alias :to_s :to_ss
45
- end
45
+ alias_method :to_s, :to_ss
46
+ end
@@ -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
- "Can't use same method."
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 = Hash.new(false)
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
@@ -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
- def start(option = [])
17
- init
18
- run
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(result = nil)
22
- if result
23
- @all_method.delete(result.first)
24
- @current_object = result.last
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 = @current_object.class
30
- rescue Exception => ex
31
- @current_class = "Undefined"
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
- $error_message = nil
60
+ @mode = mode
45
61
 
46
- loop do
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
- new_line
57
- $error_message = "Undefined object error"
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 success?
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 = "Please input first object > ")
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
- show_status
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
- command = get_command("Please input next method > ")
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
- if result = exec_method_chain(command, @current_object)
103
- if @all_method.include?(result.first)
104
- update(result)
105
- @current_chain << command
106
- elsif result.first == :exit
107
- break
108
- else
109
- $error_message = "Already used method."
110
- end
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 = [ method_name ]
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
- result << eval("object."+command)
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
@@ -1,3 +1,3 @@
1
1
  module Shiritori
2
- VERSION = "0.1.3"
2
+ VERSION = '0.1.6'
3
3
  end
@@ -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
- $stdout.puts "\n"*num
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 show_status
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 = "#{@current_chain.join('.')}"
15
- chain_size = [chain.size+PADDING, 22].max
31
+ chain = "#{current_chain.join('.')}"
32
+ chain_size = [chain.size + PADDING, 22].max
16
33
 
17
- $stdout.puts "+#{'-'*chain_size}+"
18
- $stdout.puts "|#{"Current method chain".center(chain_size)}|"
19
- $stdout.puts "+#{'-'*chain_size}+"
20
- $stdout.puts "|#{@current_chain.join('.').center(chain_size)}|"
21
- $stdout.puts "+#{'-'*chain_size}+"
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 = "#{@current_class}"
24
- obj = "#{@current_object.to_ss}"
25
- cls_size = ["#{@current_class}".size, 13].max+PADDING
26
- obj_size = ["#{@current_object}".size, 14].max+PADDING
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
- $stdout.puts "+#{'-'*(cls_size)}+#{'-'*(obj_size)}+"
30
- $stdout.puts "|#{"Current Class".center(cls_size)}|#{"Current Object".center(obj_size)}|"
31
- $stdout.puts "+#{'-'*(cls_size)}+#{'-'*(obj_size)}+"
32
- $stdout.puts "|#{cls.center(cls_size)}|#{obj.center(obj_size)}|"
33
- $stdout.puts "+#{'-'*(cls_size)}+#{'-'*(obj_size)}+"
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
- puts "Current Chain Count: #{@chain_count}"
53
+ end
54
+
55
+ def show_result
36
56
  end
37
57
  end
38
- end
58
+ end