eturem 0.3.3 → 0.4.0

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 64d7d985440e56ceded0d1713d1bb8e3a7f42285
4
- data.tar.gz: f8a30a97dba553b7e7c2f0de962b2551e6ff383a
2
+ SHA256:
3
+ metadata.gz: c96c7ae5b183ce6fc301daa33a6279158dbe2e4426dce6dde798834dc84901dc
4
+ data.tar.gz: 1bfe20edbb9da9e037b7ebe0896c62f4975631f5760fde2900ff814cc99ea3de
5
5
  SHA512:
6
- metadata.gz: fc2a5be8cd2f5471f15f0a635a6dac10e3e28eccaf169f792d64c34cd854c7b9798b2f96049ee47ffca20daf07e7885cc9677549608b161aed2478201634b051
7
- data.tar.gz: d62c5c694dbf69cee649e34dbf1cb36c2223c0cc78bf375d8d07c41d03a381fce26a3167378f42235af36f1d53f33ce0bdb9ec60b9987a2292efe7d57e6a94f9
6
+ metadata.gz: 5f929faa102e9a9b297d4732dd36cfe19a83ae3cb89b54b7ff1f60db16c4d30c872524fe6717f39120bd9096670f90c77244afa36d1e0088efe6c89b46f3becc
7
+ data.tar.gz: 044c90b8262a37e838c197002c479f913a767344065f551a9973b5cff46d904193d38f5def3d2180021452166e3c05a120be06519a95e7a8c03e6f0a1885b100
data/README.ja.md CHANGED
@@ -41,7 +41,7 @@ example1.rb:5: syntax error, unexpected end-of-input, expecting keyword_end
41
41
  Eturem を使用すると、次のようなエラー表示になります。
42
42
 
43
43
  ```
44
- ファイル"example1.rb" 5行目でエラーが発生しました。
44
+ 【エラー】ファイル"example1.rb" 5行目:
45
45
  (ただし、実際のエラーの原因はおそらくもっと前にあります。)
46
46
  構文エラーです。endが足りません。「if」に対応する「end」があるか確認してください。
47
47
  3: puts "なんたらかんたら"
@@ -74,7 +74,7 @@ did_you_mean のおかげで昔より格段にわかりやすくなったとは
74
74
  Eturem を使用すると、次のようなエラー表示になります。(実際には色付き)
75
75
 
76
76
  ```
77
- ファイル"example2.rb" 5行目でエラーが発生しました。
77
+ 【エラー】ファイル"example2.rb" 5行目:
78
78
  変数/メソッド「player_life」は存在しません。「prayer_life」の入力ミスではありませんか?
79
79
  1: prayer_life = 100
80
80
  :
@@ -110,7 +110,7 @@ example3.rb:1:in `foo': wrong number of arguments (given 1, expected 2) (Argumen
110
110
  Eturem を使用すると、次のようなエラー表示になります。
111
111
 
112
112
  ```
113
- ファイル"example3.rb" 4行目でエラーが発生しました。
113
+ 【エラー】ファイル"example3.rb" 4行目:
114
114
  引数の数が正しくありません。「foo」は本来2個の引数を取りますが、1個の引数が渡されています。
115
115
  2: end
116
116
  3: # 中略
@@ -119,6 +119,52 @@ Eturem を使用すると、次のようなエラー表示になります。
119
119
 
120
120
  このように、呼び出し行をエラー発生行として表示してくれます。
121
121
 
122
+ ### 例4:warning
123
+
124
+ 0.4.0 から、warning に対してもサポートができるようになりました。
125
+
126
+ ```
127
+ 【警告】ファイル"example4.rb" 2行目:
128
+ 条件式部分で「 = 」が使われています。「 == 」の間違いではありませんか?
129
+ => 2: puts "a" if a = 1
130
+ ```
131
+
132
+ 現状「条件式内での = 使用」のみにしか対応していませんが、上記のように日本語での警告に加えて該当行を表示することができます。
133
+
134
+ ### 例5:エラー発生時に自動で binding.irb
135
+
136
+ 変数の値が不適切だったためにエラーが起きた可能性がある場合、エラーが起きた瞬間の変数の値を調べる必要があります。そうした際には「エラー発生箇所の直前に binding.irb を入れて調べる」という手がありますが、そうするとたまにしか起きないエラーの場合何度も binding.irb が動いてしまって面倒です。
137
+
138
+ そこで、後述する設定ファイル .eturem で設定するか、あるいはプログラム中に `$eturem_repl = "irb"` と入れておくことで、エラー発生時に自動的に binding.irb することができます。
139
+
140
+ なお、この機能だけを切り出した gem「[autoirb](https://github.com/nodai2hITC/autoirb)」もあります。
141
+
142
+ ## .eturem ファイルによる設定
143
+
144
+ HOME に「.eturem」というファイルを用意すると、詳細設定ができます。
145
+
146
+ ```
147
+ enable: true
148
+ debug: false
149
+ lang: en
150
+ output_backtrace: true
151
+ output_original: true
152
+ output_script: true
153
+ use_coderay: false
154
+ before_line_num: 2
155
+ after_line_num: 2
156
+ repl: nil
157
+ ```
158
+
159
+ - enable: eturem の使用/不使用を切り替えます。
160
+ - debug: eturem 自体をデバッグするための機能なので、使う必要はありません。
161
+ - lang: 表示言語を切り替えます。ただし、`-returem/ja` のように言語を指定して使用した場合、この設定よりもそちらが優先されます。
162
+ - output_backtrace: バックトレース表示の有無を切り替えます。
163
+ - output_original: Ruby 本来のエラーメッセージの表示の有無を切り替えます。
164
+ - output_script: エラーの起きた個所のスクリプト表示の有無を切り替えます。
165
+ - before_line_num / after_line_num: スクリプト表示の際、エラー行の前後何行を表示するかを設定します。
166
+ - repl: irb または pry と書いておくと、エラー発生時に binding.irb / binding.pry します。
167
+
122
168
  ## Contributing
123
169
 
124
170
  「こう表示した方がよりわかりやすいのでは?」等のご意見ありましたら、よろしく御願いします。
data/Rakefile CHANGED
@@ -5,6 +5,7 @@ Rake::TestTask.new(:test) do |t|
5
5
  t.libs << "test"
6
6
  t.libs << "lib"
7
7
  t.test_files = FileList["test/**/*_test.rb"]
8
+ t.warning = false
8
9
  end
9
10
 
10
11
  task :default => :test
data/lib/eturem.rb CHANGED
@@ -5,37 +5,38 @@ output_backtrace = true
5
5
  output_original = true
6
6
  output_script = true
7
7
  use_coderay = false
8
- max_backtrace = 16
9
8
  before_line_num = 2
10
9
  after_line_num = 2
10
+ repl = nil
11
11
 
12
- config_file = File.join(Dir.home, ".eturem")
13
- if File.exist?(config_file)
14
- config = File.read(config_file)
15
- enable = false if config.match(/^enable\s*\:\s*(?:false|off|0)/i)
16
- debug = true if config.match(/^debug\s*\:\s*(?:true|on|1)/i)
17
- lang = Regexp.last_match(:lang) if config.match(/^lang\s*\:\s*(?<lang>\S+)/i)
18
- output_backtrace = false if config.match(/^output_backtrace\s*\:\s*(?:false|off|0)/i)
19
- output_original = false if config.match( /^output_original\s*\:\s*(?:false|off|0)/i)
20
- output_script = false if config.match( /^output_script\s*\:\s*(?:false|off|0)/i)
21
- use_coderay = true if config.match( /^use_coderay\s*\:\s*(?:true|on|1)/i)
22
- max_backtrace = Regexp.last_match(:num).to_i if config.match( /^max_backtrace\s*\:\s*(?<num>\d+)/i)
23
- before_line_num = Regexp.last_match(:num).to_i if config.match(/^before_line_num\s*\:\s*(?<num>\d+)/i)
24
- after_line_num = Regexp.last_match(:num).to_i if config.match( /^after_line_num\s*\:\s*(?<num>\d+)/i)
25
- end
26
- require "eturem/#{lang}" if enable && !defined?(Eturem)
27
-
28
- if defined? Eturem
29
- Eturem.set_config({
30
- output_backtrace: output_backtrace,
31
- output_original: output_original,
32
- output_script: output_script,
33
- use_coderay: use_coderay,
34
- max_backtrace: max_backtrace,
35
- before_line_num: before_line_num,
36
- after_line_num: after_line_num
37
- })
12
+ if File.exist?($PROGRAM_NAME)
13
+ config_file = File.join(Dir.home, ".eturem")
14
+ if File.exist?(config_file)
15
+ config = File.read(config_file)
16
+ enable = false if config.match(/^enable\s*\:\s*(?:false|off|0)/i)
17
+ debug = true if config.match(/^debug\s*\:\s*(?:true|on|1)/i)
18
+ lang = Regexp.last_match(:lang) if config.match(/^lang\s*\:\s*(?<lang>\S+)/i)
19
+ output_backtrace = false if config.match(/^output_backtrace\s*\:\s*(?:false|off|0)/i)
20
+ output_original = false if config.match( /^output_original\s*\:\s*(?:false|off|0)/i)
21
+ output_script = false if config.match( /^output_script\s*\:\s*(?:false|off|0)/i)
22
+ use_coderay = true if config.match( /^use_coderay\s*\:\s*(?:true|on|1)/i)
23
+ before_line_num = Regexp.last_match(:num).to_i if config.match(/^before_line_num\s*\:\s*(?<num>\d+)/i)
24
+ after_line_num = Regexp.last_match(:num).to_i if config.match( /^after_line_num\s*\:\s*(?<num>\d+)/i)
25
+ repl = Regexp.last_match(:repl).downcase if config.match(/^repl\s*\:\s*(?<repl>irb|pry)/i)
26
+ end
38
27
 
39
- exception = Eturem.load_and_output($0, debug)
40
- exit
28
+ if enable
29
+ require "eturem/#{lang}" unless defined?(Eturem)
30
+ Eturem.set_config(
31
+ output_backtrace: output_backtrace,
32
+ output_original: output_original,
33
+ output_script: output_script,
34
+ use_coderay: use_coderay,
35
+ before_line_num: before_line_num,
36
+ after_line_num: after_line_num
37
+ )
38
+
39
+ Eturem.load_and_output($PROGRAM_NAME, repl, debug)
40
+ exit
41
+ end
41
42
  end
data/lib/eturem/base.rb CHANGED
@@ -6,47 +6,80 @@ module Eturem
6
6
  # @return [Eturem::Base] if exception raised
7
7
  # @return [nil] if exception did not raise
8
8
  def self.load(file)
9
+ eturem = @eturem_class.new(file)
9
10
  begin
10
- Kernel.load(File.absolute_path(file))
11
+ Kernel.load(file)
11
12
  rescue Exception => exception
12
- return @eturem_class.new(exception, file) unless exception.is_a? SystemExit
13
+ raise exception if exception.is_a? SystemExit
14
+ eturem.exception = exception
13
15
  end
14
- return nil
16
+ eturem.exception ? eturem : nil
15
17
  end
16
18
 
17
- def self.load_and_output(file, debug = false)
19
+ def self.load_and_output(file, repl = nil, debug = false)
20
+ eturem = @eturem_class.new(file, true)
21
+ last_binding = nil
22
+ tp = TracePoint.trace(:raise) do |t|
23
+ last_binding = t.binding unless File.expand_path(t.path) == File.expand_path(__FILE__)
24
+ end
25
+ script = read_script(file)
18
26
  begin
19
- Kernel.load(File.absolute_path(file))
27
+ TOPLEVEL_BINDING.eval(script, file, 1)
28
+ tp.disable
29
+ eturem.comeback_stderr
20
30
  rescue Exception => exception
31
+ tp.disable
32
+ eturem.comeback_stderr
33
+ raise exception if exception.is_a? SystemExit
34
+ repl ||= $eturem_repl
35
+ use_repl = repl && last_binding && exception.is_a?(StandardError)
21
36
  begin
22
- puts @eturem_class.new(exception, file).inspect unless exception.is_a? SystemExit
37
+ eturem.exception = exception
38
+ $stderr.write eturem.inspect
23
39
  rescue Exception => e
24
- raise debug ? e : exception
40
+ raise debug ? e : eturem.exception
25
41
  end
42
+ return unless use_repl
43
+ require repl
44
+ last_binding.public_send(repl)
26
45
  end
27
46
  end
28
47
 
29
48
  def self.eval(expr, bind = nil, fname = "(eval)", lineno = 1)
49
+ eturem = @eturem_class.new(fname)
30
50
  begin
31
51
  bind ? Kernel.eval(expr, bind, fname, lineno) : Kernel.eval(expr)
32
52
  rescue Exception => exception
33
- return @eturem_class.new(exception, fname) unless exception.is_a? SystemExit
53
+ raise exception if exception.is_a? SystemExit
54
+ eturem.exception = exception
34
55
  end
35
- return nil
56
+ return eturem.exception ? eturem : nil
36
57
  end
37
58
 
38
59
  def self.set_config(config)
39
60
  @eturem_class.set_config(config)
40
61
  end
41
62
 
63
+ def self.read_script(file)
64
+ script = nil
65
+ if File.exist?(file)
66
+ script = File.binread(file)
67
+ encoding = "utf-8"
68
+ if script.match(/\A(?:#!.*\R)?#.*coding *[:=] *(?<encoding>[^\s:]+)/)
69
+ encoding = Regexp.last_match(:encoding)
70
+ end
71
+ script.force_encoding(encoding)
72
+ end
73
+ return script
74
+ end
75
+
42
76
  class Base
43
- attr_reader :exception
77
+ attr_reader :exception, :backtrace_locations, :path, :lineno, :label
44
78
 
45
79
  @@output_backtrace = true
46
80
  @@output_original = true
47
81
  @@output_script = true
48
82
  @@use_coderay = false
49
- @@max_backtrace = 16
50
83
  @@before_line_num = 2
51
84
  @@after_line_num = 2
52
85
 
@@ -61,32 +94,29 @@ module Eturem
61
94
  @@output_original = config[:output_original] if config.has_key?(:output_original)
62
95
  @@output_script = config[:output_script] if config.has_key?(:output_script)
63
96
  @@use_coderay = config[:use_coderay] if config.has_key?(:use_coderay)
64
- @@max_backtrace = config[:max_backtrace] if config.has_key?(:max_backtrace)
65
97
  @@before_line_num = config[:before_line_num] if config.has_key?(:before_line_num)
66
98
  @@after_line_num = config[:after_line_num] if config.has_key?(:after_line_num)
67
99
  end
68
100
 
69
- def initialize(exception, load_file)
101
+ def initialize(load_file, replace_stderr = false)
102
+ @load_file = load_file.encode("utf-8")
103
+ @scripts = {}
104
+ @decoration = {}
105
+ if replace_stderr
106
+ @stderr = $stderr
107
+ $stderr = self
108
+ end
109
+ end
110
+
111
+ def exception=(exception)
70
112
  @exception = exception
71
113
  @exception_s = exception.to_s
72
114
 
73
- eturem_path = File.dirname(File.absolute_path(__FILE__))
115
+ eturem_path = File.dirname(File.expand_path(__FILE__))
74
116
  @backtrace_locations = (@exception.backtrace_locations || []).reject do |location|
75
- path = File.absolute_path(location.path)
117
+ path = File.expand_path(location.path)
76
118
  path.start_with?(eturem_path) || path.end_with?("/rubygems/core_ext/kernel_require.rb")
77
119
  end
78
- @backtrace_locations.each do |location|
79
- if File.absolute_path(load_file) == location.path
80
- if load_file == $0
81
- def location.path
82
- $0
83
- end
84
- end
85
- def location.label
86
- super.sub("<top (required)>", "<main>")
87
- end
88
- end
89
- end
90
120
 
91
121
  if @exception.is_a?(SyntaxError) && @exception_s.match(/\A(?<path>.+?)\:(?<lineno>\d+)/)
92
122
  @path = Regexp.last_match(:path)
@@ -95,30 +125,41 @@ module Eturem
95
125
  backtrace_locations_shift
96
126
  end
97
127
 
98
- load_script
128
+ @script_lines = read_script(@path) || []
129
+ @output_linenos = default_output_linenos
99
130
  prepare
100
131
  end
101
132
 
102
133
  def inspect
103
- str = ""
104
- str = backtrace_inspect if @@output_backtrace
134
+ str = @@output_backtrace ? backtrace_inspect : ""
105
135
  error_message = exception_inspect
106
136
  if error_message.empty?
107
- str += original_exception_inspect
137
+ str << original_exception_inspect
108
138
  else
109
- str += original_exception_inspect + "\n" if @@output_original
110
- str += error_message + "\n"
139
+ str = "#{original_exception_inspect}\n#{str}" if @@output_original
140
+ str << "#{error_message}\n"
111
141
  end
112
- str += script_inspect if @@output_script
142
+ str << script_inspect if @@output_script
113
143
  return str
114
144
  end
115
145
 
116
146
  def backtrace_inspect
117
147
  return "" if @backtrace_locations.empty?
118
148
 
119
- str = traceback_most_recent_call_last + "\n"
120
- @backtrace_locations[0, @@max_backtrace].reverse.each_with_index do |location, i|
121
- str += sprintf("%9d: %s\n", @backtrace_locations.size - i, location_inspect(location))
149
+ str = "#{traceback_most_recent_call_last}\n"
150
+ backtraces = []
151
+ size = @backtrace_locations.size
152
+ format = "%#{8 + size.to_s.length}d: %s\n"
153
+ @backtrace_locations.reverse.each_with_index do |location, i|
154
+ backtraces.push(sprintf(format, size - i, location_inspect(location)))
155
+ end
156
+
157
+ if @exception_s == "stack level too deep"
158
+ str << backtraces[0..7].join
159
+ str << " ... #{backtraces.size - 12} levels...\n"
160
+ str << backtraces[-4..-1].join
161
+ else
162
+ str << backtraces.join
122
163
  end
123
164
  return str
124
165
  end
@@ -137,7 +178,7 @@ module Eturem
137
178
 
138
179
  def original_exception_inspect
139
180
  if @exception.is_a? SyntaxError
140
- return @exception_s
181
+ return "#{@exception_s.chomp}\n"
141
182
  else
142
183
  location_str = "#{@path}:#{@lineno}:in `#{@label}'"
143
184
  @exception_s.match(/\A(?<first_line>.*)/)
@@ -146,21 +187,45 @@ module Eturem
146
187
  end
147
188
  end
148
189
 
149
- def script_inspect
150
- return "" if @script.empty?
190
+ def script_inspect(path = @path, linenos = @output_linenos, lineno = @lineno, decoration = @decoration)
191
+ script_lines = read_script(path)
192
+ return "" unless script_lines
151
193
 
152
194
  str = ""
153
- max_lineno_length = @output_lines.max.to_s.length
154
- last_i = @output_lines.min - 1
155
- @output_lines.sort.each do |i|
156
- str += "\e[0m #{' ' * max_lineno_length} :\n" if last_i + 1 != i
157
- str += @lineno == i ? "\e[0m => \e[1;34m" : "\e[0m \e[1;34m"
158
- str += sprintf("%#{max_lineno_length}d\e[0m: %s", i, @script_lines[i])
195
+ max_lineno_length = linenos.max.to_s.length
196
+ last_i = linenos.min - 1
197
+ linenos.uniq.sort.each do |i|
198
+ line = script_lines[i]
199
+ line = highlight(line, decoration[i][0], decoration[i][1]) if decoration[i]
200
+ str << "\e[0m #{' ' * max_lineno_length} :\n" if last_i + 1 != i
201
+ str << (lineno == i ? "\e[0m => \e[1;34m" : "\e[0m \e[1;34m")
202
+ str << sprintf("%#{max_lineno_length}d\e[0m: %s\n", i, line)
159
203
  last_i = i
160
204
  end
161
205
  return str
162
206
  end
163
207
 
208
+ def write(*str)
209
+ message = nil
210
+ if str.join.force_encoding("utf-8").match(/^(.+?):(\d+):\s*warning:\s*/)
211
+ path, lineno, warning = $1, $2.to_i, $'.strip
212
+ message = warning_message(path, lineno, warning)
213
+ end
214
+ if message
215
+ @stderr.write(message)
216
+ else
217
+ @stderr.write(*str)
218
+ end
219
+ end
220
+
221
+ def comeback_stderr
222
+ $stderr = @stderr || STDERR
223
+ end
224
+
225
+ def to_s
226
+ @exception_s
227
+ end
228
+
164
229
  private
165
230
 
166
231
  def prepare
@@ -171,25 +236,23 @@ module Eturem
171
236
  end
172
237
 
173
238
  def prepare_name_error
174
- highlight!(@script_lines[@lineno], @exception.name.to_s, "\e[1;31m\e[4m")
175
239
  return unless @exception_s.match(/Did you mean\?/)
176
240
  @did_you_mean = Regexp.last_match.post_match.strip.scan(/\S+/)
177
- return if @script.empty?
241
+ @decoration[@lineno] = [@exception.name.to_s, "\e[1;31m\e[4m"]
178
242
 
179
243
  @did_you_mean.each do |name|
180
244
  index = @script_lines.index { |line| line.include?(name) }
181
245
  next unless index
182
- highlight!(@script_lines[index], name, "\e[1;33m")
183
- @output_lines.push(index)
246
+ @decoration[index] = [name, "\e[1;33m"]
247
+ @output_linenos.push(index)
184
248
  end
185
249
  end
186
250
 
187
251
  def prepare_argument_error
188
252
  @method = @label
189
- old_path = @path
190
253
  backtrace_locations_shift
191
- load_script unless old_path == @path
192
- @output_lines = default_output_lines
254
+ @script_lines = read_script(@path)
255
+ @output_linenos = default_output_linenos
193
256
  end
194
257
 
195
258
  def backtrace_locations_shift
@@ -207,37 +270,38 @@ module Eturem
207
270
  "from #{location.path}:#{location.lineno}:in `#{location.label}'"
208
271
  end
209
272
 
210
- def load_script
211
- @script ||= ""
212
- if @path && File.exist?(@path)
213
- @script = File.binread(@path)
214
- encoding = "utf-8"
215
- if @script.match(/\A(?:#!.*\R)?#.*coding *[:=] *(?<encoding>[^\s:]+)/)
216
- encoding = Regexp.last_match(:encoding)
217
- end
218
- @script.force_encoding(encoding)
219
- end
220
- if @@use_coderay
221
- require "coderay"
222
- @script = CodeRay.scan(@script, :ruby).terminal
223
- end
224
- @script_lines = @script.lines
225
- @script_lines.unshift("")
226
- @output_lines = default_output_lines
273
+ def default_output_linenos
274
+ from = [1, @lineno - @@before_line_num].max
275
+ to = [@script_lines.size - 1, @lineno + @@after_line_num].min
276
+ (from..to).to_a
227
277
  end
228
278
 
229
279
  def highlight(str, keyword, color)
230
- str.to_s.gsub(keyword){ color + ($1 || $&) + "\e[0m" }
280
+ str.to_s.gsub(keyword){ "#{color}#{$&}\e[0m" }
231
281
  end
232
282
 
233
- def highlight!(str, keyword, color)
234
- str.gsub!(keyword){ color + ($1 || $&) + "\e[0m" } if str
283
+ def warning_message(file, line, warning)
284
+ case warning
285
+ when "found `= literal' in conditional, should be =="
286
+ "#{file}:#{line}: warning: #{warning}\n" +
287
+ script_inspect(file, [line], line, { line => [/(?<![><!=])=(?!=)/, "\e[1;31m\e[4m"] })
288
+ else
289
+ nil
290
+ end
235
291
  end
236
292
 
237
- def default_output_lines
238
- from = [1, @lineno - @@before_line_num].max
239
- to = [@script_lines.size - 1, @lineno + @@after_line_num].min
240
- (from..to).to_a
293
+ def read_script(file)
294
+ unless @scripts[file]
295
+ script = Eturem.read_script(file)
296
+ return nil unless script
297
+ script.encode!("utf-8")
298
+ if @@use_coderay
299
+ require "coderay"
300
+ script = CodeRay.scan(script, :ruby).terminal
301
+ end
302
+ @scripts[file] = [""] + script.lines(chomp: true)
303
+ end
304
+ return @scripts[file]
241
305
  end
242
306
  end
243
307
 
data/lib/eturem/ja.rb CHANGED
@@ -206,18 +206,19 @@ module Eturem
206
206
  end
207
207
 
208
208
  def traceback_most_recent_call_last
209
- "エラー発生までの流れ:"
209
+ "Traceback(エラー発生までの流れを直前のものほど下に表示しています。):"
210
210
  end
211
211
 
212
212
  def location_inspect(location)
213
- %["#{location.path}" #{location.lineno}行目: '#{location.label}']
213
+ %<"#{location.path}" #{location.lineno}行目: '#{location.label}'>
214
214
  end
215
215
 
216
216
  def exception_inspect
217
217
  error_message = super
218
218
  error_message = "#{@exception_s} (#{@exception.class})" if error_message.empty?
219
- return (@path == "(eval)" ? "eval 中の" : %[ファイル"#{@path}"]) +
220
- " #{@lineno}行目でエラーが発生しました。\n" + error_message
219
+ return "\e[1;31m【エラー】\e[0m" +
220
+ (@path == "(eval)" ? "eval 中の" : %<ファイル"#{@path}">) +
221
+ " #{@lineno}行目:\n#{error_message}"
221
222
  end
222
223
 
223
224
  def no_memory_error_inspect
@@ -225,8 +226,8 @@ module Eturem
225
226
  end
226
227
 
227
228
  def load_error_inspect
228
- %[ファイル/ライブラリ "#{@exception.path}" が見つかりません。] +
229
- %[ファイル/ライブラリ名を確認してください。]
229
+ %<ファイル/ライブラリ "#{@exception.path}" が見つかりません。> +
230
+ %<ファイル/ライブラリ名を確認してください。>
230
231
  end
231
232
 
232
233
  def syntax_error_inspect
@@ -239,13 +240,13 @@ module Eturem
239
240
  end
240
241
  end
241
242
  if unexpected.match(/^'(.)'$/)
242
- highlight!(@script_lines[@lineno], Regexp.last_match(1), "\e[1;31m\e[4m")
243
+ @decoration[@lineno] = [Regexp.last_match(1), "\e[1;31m\e[4m"]
243
244
  elsif
244
- highlight!(@script_lines[@lineno], unexpected, "\e[1;31m\e[4m")
245
+ @decoration[@lineno] = [unexpected, "\e[1;31m\e[4m"]
245
246
  end
246
247
 
247
248
  keywords = %w[if unless case while until for begin def class module do].select do |keyword|
248
- @script.index(keyword)
249
+ @script_lines.join.index(keyword)
249
250
  end
250
251
  keywords = "「#{keywords.join(' / ')}」"
251
252
  keywords = "ifなど" if keywords == "「」"
@@ -265,7 +266,7 @@ module Eturem
265
266
  return ""
266
267
  elsif @exception_s.match(/Invalid (?<invalid>(?:break|next|retry|redo|yield))/)
267
268
  invalid = Regexp.last_match(:invalid)
268
- highlight!(@script_lines[@lineno], invalid, "\e[1;31m\e[4m")
269
+ @decoration[@lineno] = [invalid, "\e[1;31m\e[4m"]
269
270
  return "#{invalid} が不適切な場所にあります。"
270
271
  elsif @exception_s.match(/unterminated string meets end of file/)
271
272
  return "「\"」「'」が閉じられていません。"
@@ -300,18 +301,18 @@ module Eturem
300
301
  ret = "引数の数が正しくありません。「#{@method}」は本来"
301
302
  case expected
302
303
  when "0"
303
- ret += "引数が不要です"
304
+ ret << "引数が不要です"
304
305
  when /^(\d+)\.\.(\d+)$/
305
- ret += "#{Regexp.last_match(1)}~#{Regexp.last_match(2)}個の引数を取ります"
306
+ ret << "#{Regexp.last_match(1)}~#{Regexp.last_match(2)}個の引数を取ります"
306
307
  when /^(\d+)\+$/
307
- ret += "#{Regexp.last_match(1)}個以上の引数を取ります"
308
+ ret << "#{Regexp.last_match(1)}個以上の引数を取ります"
308
309
  else
309
- ret += "#{expected}個の引数を取ります"
310
+ ret << "#{expected}個の引数を取ります"
310
311
  end
311
312
  if given == 0
312
- ret += "が、引数が1つも渡されていません。"
313
+ ret << "が、引数が1つも渡されていません。"
313
314
  else
314
- ret += "が、#{given}個の引数が渡されています。"
315
+ ret << "が、#{given}個の引数が渡されています。"
315
316
  end
316
317
  return ret
317
318
  else
@@ -325,16 +326,21 @@ module Eturem
325
326
 
326
327
  def name_error_inspect
327
328
  if @exception.name.to_s.encode("UTF-8").include?(" ")
328
- load_script
329
- highlight!(@script_lines[@lineno], @exception.name.to_s, "\e[1;31m\e[4m")
329
+ @decoration[@lineno] = [/ +/, "\e[1;31m\e[4m"]
330
330
  return "スクリプト中に全角空白が混じっています。"
331
331
  end
332
332
 
333
+ if @exception.receiver == nil
334
+ ret = "nil に対して #{@exception.name} というメソッドを呼び出そうとしています。\n"
335
+ ret << "変数の値/メソッドの返値が予期せず nil になっている可能性があります。"
336
+ return ret
337
+ end
338
+
333
339
  ret = "#{@exception.is_a?(NoMethodError) ? "" : "変数/"}メソッド" +
334
340
  "「\e[1;31m\e[4m#{@exception.name}\e[0m」は存在しません。"
335
341
  if @did_you_mean
336
342
  did_you_mean = @did_you_mean.map{ |d| "\e[1;33m#{d}\e[0m" }.join(" / ")
337
- ret += "「#{did_you_mean}」の入力ミスではありませんか?"
343
+ ret << "「#{did_you_mean}」の入力ミスではありませんか?"
338
344
  end
339
345
  return ret
340
346
  end
@@ -354,6 +360,21 @@ module Eturem
354
360
  def system_stack_error_inspect
355
361
  "システムスタックがあふれました。意図しない無限ループが生じている可能性があります。"
356
362
  end
363
+
364
+ def warning_message(file, line, warning)
365
+ message = super
366
+ case warning
367
+ when "found `= literal' in conditional, should be =="
368
+ original, script = message.split("\n", 2)
369
+ message = @@output_original ? "#{original}\n" : ""
370
+ message += "\e[1;31m【警告】\e[0m" +
371
+ (file == "(eval)" ? "eval 中の" : %<ファイル"#{file}">) +
372
+ " #{line}行目:\n" +
373
+ "条件式部分で「 = 」が使われています。「 == 」の間違いではありませんか?\n"
374
+ message += @@output_script ? script : "\n"
375
+ end
376
+ return message
377
+ end
357
378
  end
358
379
 
359
380
  @eturem_class = Ja
@@ -1,3 +1,3 @@
1
1
  module Eturem
2
- VERSION = "0.3.3"
2
+ VERSION = "0.4.0"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: eturem
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.3
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - nodai2hITC
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2018-10-06 00:00:00.000000000 Z
11
+ date: 2019-09-20 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -93,8 +93,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
93
93
  - !ruby/object:Gem::Version
94
94
  version: '0'
95
95
  requirements: []
96
- rubyforge_project:
97
- rubygems_version: 2.6.12
96
+ rubygems_version: 3.0.1
98
97
  signing_key:
99
98
  specification_version: 4
100
99
  summary: Easy To Understand Ruby Error Message.