summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--include/mruby/variable.h1
-rwxr-xr-xminirake2
-rw-r--r--mrblib/string.rb4
-rw-r--r--src/class.c88
-rw-r--r--src/variable.c9
-rw-r--r--test/assert.rb42
-rw-r--r--test/t/module.rb22
-rw-r--r--test/t/string.rb8
-rw-r--r--tools/mirb/mirb.c4
9 files changed, 126 insertions, 54 deletions
diff --git a/include/mruby/variable.h b/include/mruby/variable.h
index f2f22e65a..a1f52217d 100644
--- a/include/mruby/variable.h
+++ b/include/mruby/variable.h
@@ -37,6 +37,7 @@ void mrb_vm_const_set(mrb_state*, mrb_sym, mrb_value);
mrb_value mrb_const_get(mrb_state*, mrb_value, mrb_sym);
void mrb_const_set(mrb_state*, mrb_value, mrb_sym, mrb_value);
int mrb_const_defined(mrb_state*, mrb_value, mrb_sym);
+void mrb_const_remove(mrb_state*, mrb_value, mrb_sym);
mrb_value mrb_obj_iv_get(mrb_state *mrb, struct RObject *obj, mrb_sym sym);
void mrb_obj_iv_set(mrb_state *mrb, struct RObject *obj, mrb_sym sym, mrb_value v);
diff --git a/minirake b/minirake
index 430e730cb..45ae797a9 100755
--- a/minirake
+++ b/minirake
@@ -287,7 +287,7 @@ module MiniRake
end
Rake = MiniRake
-include MiniRake::DSL
+extend MiniRake::DSL
######################################################################
diff --git a/mrblib/string.rb b/mrblib/string.rb
index 9b11bb2e5..8a4894dd4 100644
--- a/mrblib/string.rb
+++ b/mrblib/string.rb
@@ -28,8 +28,10 @@ class String
#
# ISO 15.2.10.5.18
def gsub(*args, &block)
+ lc = ''
if args.size == 2
- split(args[0]).join(args[1])
+ lc = args[1] if self[-1] == args[0]
+ split(args[0]).join(args[1]) + lc
elsif args.size == 1 && block
split(args[0]).join(block.call(args[0]))
else
diff --git a/src/class.c b/src/class.c
index 136a07cb6..e70bd7e73 100644
--- a/src/class.c
+++ b/src/class.c
@@ -600,9 +600,14 @@ mrb_get_args(mrb_state *mrb, const char *format, ...)
if (mrb_type(ss) == MRB_TT_SYMBOL) {
*symp = mrb_symbol(ss);
}
- else {
+ else if (mrb_string_p(ss)) {
*symp = mrb_intern_str(mrb, to_str(mrb, ss));
}
+ else {
+ mrb_value obj = mrb_funcall(mrb, ss, "inspect", 0);
+ mrb_raisef(mrb, E_TYPE_ERROR, "%s is not a symbol",
+ mrb_string_value_ptr(mrb, obj));
+ }
i++;
}
}
@@ -1453,20 +1458,6 @@ mod_define_method(mrb_state *mrb, mrb_value self)
return blk;
}
-static mrb_sym
-mrb_sym_value(mrb_state *mrb, mrb_value val)
-{
- if (mrb_string_p(val)) {
- return mrb_intern_str(mrb, val);
- }
- else if(!mrb_symbol_p(val)) {
- mrb_value obj = mrb_funcall(mrb, val, "inspect", 0);
- mrb_raisef(mrb, E_TYPE_ERROR, "%s is not a symbol",
- mrb_string_value_ptr(mrb, obj));
- }
- return mrb_symbol(val);
-}
-
static void
check_cv_name(mrb_state *mrb, mrb_sym id)
{
@@ -1497,13 +1488,10 @@ check_cv_name(mrb_state *mrb, mrb_sym id)
static mrb_value
mrb_mod_cvar_defined(mrb_state *mrb, mrb_value mod)
{
- mrb_value sym;
mrb_sym id;
- mrb_get_args(mrb, "o", &sym);
+ mrb_get_args(mrb, "n", &id);
- id = mrb_sym_value(mrb,sym);
check_cv_name(mrb, id);
-
if(mrb_cv_defined(mrb, mod, id))
return mrb_true_value();
return mrb_false_value();
@@ -1527,11 +1515,9 @@ mrb_mod_cvar_defined(mrb_state *mrb, mrb_value mod)
static mrb_value
mrb_mod_cvar_get(mrb_state *mrb, mrb_value mod)
{
- mrb_value sym;
mrb_sym id;
- mrb_get_args(mrb, "o", &sym);
- id = mrb_sym_value(mrb,sym);
+ mrb_get_args(mrb, "n", &id);
check_cv_name(mrb, id);
return mrb_cv_get(mrb, mod, id);
}
@@ -1557,12 +1543,10 @@ mrb_mod_cvar_get(mrb_state *mrb, mrb_value mod)
static mrb_value
mrb_mod_cvar_set(mrb_state *mrb, mrb_value mod)
{
- mrb_value sym, value;
+ mrb_value value;
mrb_sym id;
- mrb_get_args(mrb, "oo", &sym, &value);
-
- id = mrb_sym_value(mrb,sym);
+ mrb_get_args(mrb, "no", &id, &value);
check_cv_name(mrb, id);
mrb_cv_set(mrb, mod, id, value);
return value;
@@ -1594,16 +1578,13 @@ mrb_mod_cvar_set(mrb_state *mrb, mrb_value mod)
mrb_value
mrb_mod_remove_cvar(mrb_state *mrb, mrb_value mod)
{
- mrb_value sym, val;
+ mrb_value val;
mrb_sym id;
- mrb_get_args(mrb, "o", &sym);
-
- id = mrb_sym_value(mrb,sym);
+ mrb_get_args(mrb, "n", &id);
check_cv_name(mrb, id);
val = mrb_iv_remove(mrb, mod, id);
-
if (!mrb_undef_p(val)) return val;
if (mrb_cv_defined(mrb, mod, id)){
@@ -1648,12 +1629,9 @@ mrb_mod_remove_cvar(mrb_state *mrb, mrb_value mod)
static mrb_value
mrb_mod_method_defined(mrb_state *mrb, mrb_value mod)
{
- mrb_value sym;
mrb_sym id;
- mrb_get_args(mrb, "o", &sym);
- id = mrb_sym_value(mrb,sym);
-
+ mrb_get_args(mrb, "n", &id);
if (mrb_obj_respond_to(mrb_class_ptr(mod), id)) {
return mrb_true_value();
}
@@ -1717,11 +1695,11 @@ check_const_name(mrb_state *mrb, mrb_sym id)
mrb_value
mrb_mod_const_defined(mrb_state *mrb, mrb_value mod)
{
- mrb_value sym;
- mrb_get_args(mrb, "o", &sym);
+ mrb_sym id;
- check_const_name(mrb, mrb_sym_value(mrb,sym));
- if(mrb_const_defined(mrb, mod, mrb_sym_value(mrb, sym))) {
+ mrb_get_args(mrb, "n", &id);
+ check_const_name(mrb, id);
+ if(mrb_const_defined(mrb, mod, id)) {
return mrb_true_value();
}
return mrb_false_value();
@@ -1730,24 +1708,39 @@ mrb_mod_const_defined(mrb_state *mrb, mrb_value mod)
mrb_value
mrb_mod_const_get(mrb_state *mrb, mrb_value mod)
{
- mrb_value sym;
- mrb_get_args(mrb, "o", &sym);
+ mrb_sym id;
- check_const_name(mrb, mrb_sym_value(mrb,sym));
- return mrb_const_get(mrb, mod, mrb_sym_value(mrb, sym));
+ mrb_get_args(mrb, "n", &id);
+ check_const_name(mrb, id);
+ return mrb_const_get(mrb, mod, id);
}
mrb_value
mrb_mod_const_set(mrb_state *mrb, mrb_value mod)
{
- mrb_value sym, value;
- mrb_get_args(mrb, "oo", &sym, &value);
+ mrb_sym id;
+ mrb_value value;
- check_const_name(mrb, mrb_sym_value(mrb,sym));
- mrb_const_set(mrb, mod, mrb_sym_value(mrb, sym), value);
+ mrb_get_args(mrb, "no", &id, &value);
+ check_const_name(mrb, id);
+ mrb_const_set(mrb, mod, id, value);
return value;
}
+mrb_value
+mrb_mod_remove_const(mrb_state *mrb, mrb_value mod)
+{
+ mrb_sym id;
+ mrb_value val;
+
+ mrb_get_args(mrb, "n", &id);
+ check_const_name(mrb, id);
+ val = mrb_iv_remove(mrb, mod, id);
+ if (mrb_undef_p(val)) {
+ mrb_name_error(mrb, id, "constant %s not defined", mrb_sym2name(mrb, id));
+ }
+ return val;
+}
static mrb_value
mrb_mod_eqq(mrb_state *mrb, mrb_value mod)
@@ -1828,6 +1821,7 @@ mrb_init_class(mrb_state *mrb)
mrb_define_method(mrb, mod, "const_defined?", mrb_mod_const_defined, ARGS_REQ(1)); /* 15.2.2.4.20 */
mrb_define_method(mrb, mod, "const_get", mrb_mod_const_get, ARGS_REQ(1)); /* 15.2.2.4.21 */
mrb_define_method(mrb, mod, "const_set", mrb_mod_const_set, ARGS_REQ(2)); /* 15.2.2.4.23 */
+ mrb_define_method(mrb, mod, "remove_const", mrb_mod_remove_const, ARGS_REQ(1)); /* 15.2.2.4.40 */
mrb_define_method(mrb, mod, "define_method", mod_define_method, ARGS_REQ(1));
mrb_define_method(mrb, mod, "class_variables", mrb_mod_class_variables, ARGS_NONE()); /* 15.2.2.4.19 */
diff --git a/src/variable.c b/src/variable.c
index 6661dae40..a2dca3cc6 100644
--- a/src/variable.c
+++ b/src/variable.c
@@ -885,7 +885,7 @@ mrb_const_set(mrb_state *mrb, mrb_value mod, mrb_sym sym, mrb_value v)
mrb_iv_set(mrb, mod, sym, v);
}
-void
+ void
mrb_vm_const_set(mrb_state *mrb, mrb_sym sym, mrb_value v)
{
struct RClass *c = mrb->ci->proc->target_class;
@@ -895,6 +895,13 @@ mrb_vm_const_set(mrb_state *mrb, mrb_sym sym, mrb_value v)
}
void
+mrb_const_remove(mrb_state *mrb, mrb_value mod, mrb_sym sym)
+{
+ mod_const_check(mrb, mod);
+ mrb_iv_remove(mrb, mod, sym);
+}
+
+void
mrb_define_const(mrb_state *mrb, struct RClass *mod, const char *name, mrb_value v)
{
mrb_obj_iv_set(mrb, (struct RObject*)mod, mrb_intern(mrb, name), v);
diff --git a/test/assert.rb b/test/assert.rb
index 218a911d4..9f3231cd4 100644
--- a/test/assert.rb
+++ b/test/assert.rb
@@ -11,6 +11,11 @@ def assertion_string(err, str, iso=nil, e=nil)
msg += " [#{iso}]" if iso && iso != ''
msg += " => #{e.message}" if e
msg += " (mrbgems: #{GEMNAME})" if Object.const_defined?(:GEMNAME)
+ if $mrbtest_assert && $mrbtest_assert.size > 0
+ $mrbtest_assert.each do |idx, str, diff|
+ msg += "\n - Assertion[#{idx}] Failed: #{str}\n#{diff}"
+ end
+ end
msg
end
@@ -25,8 +30,10 @@ end
def assert(str = 'Assertion failed', iso = '')
print(str, (iso != '' ? " [#{iso}]" : ''), ' : ') if $mrbtest_verbose
begin
- if(!yield)
- $asserts.push(assertion_string('Fail: ', str, iso))
+ $mrbtest_assert = []
+ $mrbtest_assert_idx = 0
+ if(!yield || $mrbtest_assert.size > 0)
+ $asserts.push(assertion_string('Fail: ', str, iso, nil))
$ko_test += 1
print('F')
else
@@ -37,10 +44,41 @@ def assert(str = 'Assertion failed', iso = '')
$asserts.push(assertion_string('Error: ', str, iso, e))
$kill_test += 1
print('X')
+ ensure
+ $mrbtest_assert = nil
end
print("\n") if $mrbtest_verbose
end
+def assertion_diff(exp, act)
+ " Expected: #{exp.inspect}\n" +
+ " Actual: #{act.inspect}"
+end
+
+def assert_true(ret, msg = nil, diff = nil)
+ if $mrbtest_assert
+ $mrbtest_assert_idx += 1
+ if !ret
+ msg = "Expected #{ret.inspect} to be true" unless msg
+ diff = assertion_diff(true, ret) unless diff
+ $mrbtest_assert.push([$mrbtest_assert_idx, msg, diff])
+ end
+ end
+ ret
+end
+
+def assert_equal(exp, act, msg = nil)
+ msg = "Expected to be equal" unless msg
+ diff = assertion_diff(exp, act)
+ assert_true(exp == act, msg, diff)
+end
+
+def assert_nil(obj, msg = nil)
+ msg = "Expected #{obj.inspect} to be nil" unless msg
+ diff = assertion_diff(nil, obj)
+ assert_true(obj.nil?, msg, diff)
+end
+
##
# Report the test result and print all assertions
# which were reported broken.
diff --git a/test/t/module.rb b/test/t/module.rb
index 286c2c085..6c1c1acda 100644
--- a/test/t/module.rb
+++ b/test/t/module.rb
@@ -241,6 +241,28 @@ assert('Module#remove_class_variable', '15.2.2.4.39') do
not Test4RemoveClassVariable.class_variables.include? :@@cv
end
+assert('Module#remove_const', '15.2.2.4.40') do
+ module Test4RemoveConst
+ ExistingConst = 23
+ end
+
+ result = Test4RemoveConst.module_eval { remove_const :ExistingConst }
+
+ name_error = false
+ begin
+ Test4RemoveConst.module_eval { remove_const :NonExistingConst }
+ rescue NameError
+ name_error = true
+ end
+
+ # Constant removed from Module
+ not Test4RemoveConst.const_defined? :ExistingConst and
+ # Return value of binding
+ result == 23 and
+ # Name Error raised when Constant doesn't exist
+ name_error
+end
+
assert('Module#remove_method', '15.2.2.4.41') do
module Test4RemoveMethod
class Parent
diff --git a/test/t/string.rb b/test/t/string.rb
index fac77075b..7d0b147d0 100644
--- a/test/t/string.rb
+++ b/test/t/string.rb
@@ -193,7 +193,9 @@ assert('String#eql?', '15.2.10.5.17') do
end
assert('String#gsub', '15.2.10.5.18') do
- 'abcabc'.gsub('b', 'B') == 'aBcaBc' && 'abcabc'.gsub('b') { |w| w.capitalize } == 'aBcaBc'
+ 'abcabc'.gsub('b', 'B') == 'aBcaBc' and
+ 'abcabc'.gsub('b') { |w| w.capitalize } == 'aBcaBc' and
+ '#a#a#'.gsub('#', '$') == '$a$a$'
end
assert('String#gsub!', '15.2.10.5.19') do
@@ -318,7 +320,9 @@ assert('String#split', '15.2.10.5.35') do
end
assert('String#sub', '15.2.10.5.36') do
- 'abcabc'.sub('b', 'B') == 'aBcabc' && 'abcabc'.sub('b') { |w| w.capitalize } == 'aBcabc'
+ 'abcabc'.sub('b', 'B') == 'aBcabc' and
+ 'abcabc'.sub('b') { |w| w.capitalize } == 'aBcabc' and
+ 'aa#'.sub('#', '$') == 'aa$'
end
assert('String#sub!', '15.2.10.5.37') do
diff --git a/tools/mirb/mirb.c b/tools/mirb/mirb.c
index 85c3249d2..29685cf28 100644
--- a/tools/mirb/mirb.c
+++ b/tools/mirb/mirb.c
@@ -191,6 +191,10 @@ main(void)
last_code_line[char_index] = '\0';
#else
char* line = readline(code_block_open ? "* " : "> ");
+ if(line == NULL) {
+ printf("\n");
+ break;
+ }
strncat(last_code_line, line, sizeof(last_code_line)-1);
add_history(line);
free(line);