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.
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