diff options
| -rw-r--r-- | include/mruby/error.h | 1 | ||||
| -rw-r--r-- | mrbgems/mruby-string-ext/mrblib/string.rb | 79 | ||||
| -rw-r--r-- | mrblib/error.rb | 6 | ||||
| -rw-r--r-- | src/class.c | 3 | ||||
| -rw-r--r-- | src/error.c | 14 | ||||
| -rw-r--r-- | src/parse.y | 6 | ||||
| -rw-r--r-- | src/vm.c | 2 | ||||
| -rw-r--r-- | tasks/mrbgem_spec.rake | 3 | ||||
| -rw-r--r-- | test/t/nomethoderror.rb | 13 |
9 files changed, 110 insertions, 17 deletions
diff --git a/include/mruby/error.h b/include/mruby/error.h index 7ae2d4348..4d37f1701 100644 --- a/include/mruby/error.h +++ b/include/mruby/error.h @@ -19,6 +19,7 @@ void mrb_exc_print(mrb_state *mrb, struct RObject *exc); void mrb_print_backtrace(mrb_state *mrb); mrb_value mrb_exc_backtrace(mrb_state *mrb, mrb_value exc); mrb_value mrb_get_backtrace(mrb_state *mrb); +mrb_noreturn void mrb_no_method_error(mrb_state *mrb, mrb_sym id, mrb_int argc, const mrb_value *argv, const char *fmt, ...); /* declaration for fail method */ mrb_value mrb_f_raise(mrb_state*, mrb_value); diff --git a/mrbgems/mruby-string-ext/mrblib/string.rb b/mrbgems/mruby-string-ext/mrblib/string.rb index 45c631b94..a08fc0f46 100644 --- a/mrbgems/mruby-string-ext/mrblib/string.rb +++ b/mrbgems/mruby-string-ext/mrblib/string.rb @@ -1,4 +1,14 @@ class String + ## + # call-seq: + # str.lstrip -> new_str + # + # Returns a copy of <i>str</i> with leading whitespace removed. See also + # <code>String#rstrip</code> and <code>String#strip</code>. + # + # " hello ".lstrip #=> "hello " + # "hello".lstrip #=> "hello" + # def lstrip a = 0 z = self.size - 1 @@ -6,6 +16,16 @@ class String (z >= 0) ? self[a..z] : "" end + ## + # call-seq: + # str.rstrip -> new_str + # + # Returns a copy of <i>str</i> with trailing whitespace removed. See also + # <code>String#lstrip</code> and <code>String#strip</code>. + # + # " hello ".rstrip #=> " hello" + # "hello".rstrip #=> "hello" + # def rstrip a = 0 z = self.size - 1 @@ -13,6 +33,15 @@ class String (z >= 0) ? self[a..z] : "" end + ## + # call-seq: + # str.strip -> new_str + # + # Returns a copy of <i>str</i> with leading and trailing whitespace removed. + # + # " hello ".strip #=> "hello" + # "\tgoodbye\r\n".strip #=> "goodbye" + # def strip a = 0 z = self.size - 1 @@ -21,31 +50,61 @@ class String (z >= 0) ? self[a..z] : "" end + ## + # call-seq: + # str.lstrip! -> self or nil + # + # Removes leading whitespace from <i>str</i>, returning <code>nil</code> if no + # change was made. See also <code>String#rstrip!</code> and + # <code>String#strip!</code>. + # + # " hello ".lstrip #=> "hello " + # "hello".lstrip! #=> nil + # def lstrip! s = self.lstrip (s == self) ? nil : self.replace(s) end + ## + # call-seq: + # str.rstrip! -> self or nil + # + # Removes trailing whitespace from <i>str</i>, returning <code>nil</code> if + # no change was made. See also <code>String#lstrip!</code> and + # <code>String#strip!</code>. + # + # " hello ".rstrip #=> " hello" + # "hello".rstrip! #=> nil + # def rstrip! s = self.rstrip (s == self) ? nil : self.replace(s) end + ## + # call-seq: + # str.strip! -> str or nil + # + # Removes leading and trailing whitespace from <i>str</i>. Returns + # <code>nil</code> if <i>str</i> was not altered. + # def strip! s = self.strip (s == self) ? nil : self.replace(s) end -# call-seq: -# str.casecmp(other_str) -> -1, 0, +1 or nil -# -# Case-insensitive version of <code>String#<=></code>. -# -# "abcdef".casecmp("abcde") #=> 1 -# "aBcDeF".casecmp("abcdef") #=> 0 -# "abcdef".casecmp("abcdefg") #=> -1 -# "abcdef".casecmp("ABCDEF") #=> 0 -# + ## + # call-seq: + # str.casecmp(other_str) -> -1, 0, +1 or nil + # + # Case-insensitive version of <code>String#<=></code>. + # + # "abcdef".casecmp("abcde") #=> 1 + # "aBcDeF".casecmp("abcdef") #=> 0 + # "abcdef".casecmp("abcdefg") #=> -1 + # "abcdef".casecmp("ABCDEF") #=> 0 + # def casecmp(str) self.downcase <=> str.to_str.downcase rescue NoMethodError diff --git a/mrblib/error.rb b/mrblib/error.rb index 6e8181e9d..a5b6b3223 100644 --- a/mrblib/error.rb +++ b/mrblib/error.rb @@ -48,6 +48,12 @@ end # ISO 15.2.32 class NoMethodError < NameError + attr_reader :args + + def initialize(message=nil, name=nil, args=nil) + @args = args + super message, name + end end # ISO 15.2.33 diff --git a/src/class.c b/src/class.c index db9a8ac26..ba078911b 100644 --- a/src/class.c +++ b/src/class.c @@ -1216,8 +1216,7 @@ mrb_bob_missing(mrb_state *mrb, mrb_value mod) repr = mrb_any_to_s(mrb, mod); } - mrb_raisef(mrb, E_NOMETHOD_ERROR, "undefined method '%S' for %S", - mrb_sym2str(mrb, name), repr); + mrb_no_method_error(mrb, name, alen, a, "undefined method '%S' for %S", mrb_sym2str(mrb, name), repr); /* not reached */ return mrb_nil_value(); } diff --git a/src/error.c b/src/error.c index 360df8f2e..c60fff10d 100644 --- a/src/error.c +++ b/src/error.c @@ -442,6 +442,20 @@ mrb_sys_fail(mrb_state *mrb, const char *mesg) } } +mrb_noreturn void +mrb_no_method_error(mrb_state *mrb, mrb_sym id, mrb_int argc, const mrb_value *argv, char const* fmt, ...) +{ + mrb_value exc; + va_list ap; + + va_start(ap, fmt); + exc = mrb_funcall(mrb, mrb_obj_value(E_NOMETHOD_ERROR), "new", 3, + mrb_vformat(mrb, fmt, ap), mrb_symbol_value(id), + mrb_ary_new_from_values(mrb, argc, argv)); + va_end(ap); + mrb_exc_raise(mrb, exc); +} + void mrb_init_exception(mrb_state *mrb) { diff --git a/src/parse.y b/src/parse.y index 719e78218..93923aa71 100644 --- a/src/parse.y +++ b/src/parse.y @@ -2875,15 +2875,15 @@ var_ref : variable | keyword_self { $$ = new_self(p); - } + } | keyword_true { $$ = new_true(p); - } + } | keyword_false { $$ = new_false(p); - } + } | keyword__FILE__ { if (!p->filename) { @@ -811,7 +811,7 @@ RETRY_TRY_BLOCK: CASE(OP_LOADL) { /* A Bx R(A) := Pool(Bx) */ - regs[GETARG_A(i)] = pool[GETARG_Bx(i)]; + regs[GETARG_A(i)] = pool[GETARG_Bx(i)]; NEXT; } diff --git a/tasks/mrbgem_spec.rake b/tasks/mrbgem_spec.rake index 67edffbc5..36dd8f9c1 100644 --- a/tasks/mrbgem_spec.rake +++ b/tasks/mrbgem_spec.rake @@ -44,7 +44,7 @@ module MRuby end def run_test_in_other_mrb_state? - not test_preload.nil? or not test_objs.empty? + not test_preload.nil? or not test_objs.empty? or not test_args.empty? end def setup @@ -182,6 +182,7 @@ module MRuby f.puts %Q[#include "mruby/irep.h"] f.puts %Q[#include "mruby/string.h"] f.puts %Q[#include "mruby/variable.h"] + f.puts %Q[#include "mruby/hash.h"] unless test_args.empty? end def version_ok?(req_versions) diff --git a/test/t/nomethoderror.rb b/test/t/nomethoderror.rb index 561e545f9..709d31165 100644 --- a/test/t/nomethoderror.rb +++ b/test/t/nomethoderror.rb @@ -11,3 +11,16 @@ end assert('NoMethodError superclass', '15.2.32.2') do assert_equal NameError, NoMethodError.superclass end + +assert('NoMethodError#args', '15.2.32.2.1') do + a = NoMethodError.new 'test', :test, [1, 2] + assert_equal [1, 2], a.args + + assert_nothing_raised do + begin + doesNotExistAsAMethodNameForVerySure 3, 1, 4 + rescue NoMethodError => e + assert_equal [3, 1, 4], e.args + end + end +end |
