summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--include/mruby/error.h1
-rw-r--r--mrbgems/mruby-string-ext/mrblib/string.rb79
-rw-r--r--mrblib/error.rb6
-rw-r--r--src/class.c3
-rw-r--r--src/error.c14
-rw-r--r--src/parse.y6
-rw-r--r--src/vm.c2
-rw-r--r--tasks/mrbgem_spec.rake3
-rw-r--r--test/t/nomethoderror.rb13
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) {
diff --git a/src/vm.c b/src/vm.c
index d604e5d9e..41b5ca57f 100644
--- a/src/vm.c
+++ b/src/vm.c
@@ -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