diff --git a/mrbgems/mruby-bin-mruby/bintest/mruby.rb b/mrbgems/mruby-bin-mruby/bintest/mruby.rb index 27283d3d9..0301871d0 100644 --- a/mrbgems/mruby-bin-mruby/bintest/mruby.rb +++ b/mrbgems/mruby-bin-mruby/bintest/mruby.rb @@ -176,3 +176,17 @@ assert('top level local variables are in file scope') do assert_mruby("[1, -2, 3]\n5\n6\n", "", true, ["-r", crb.path, drb.path]) assert_mruby("[1, -2, 3]\n5\n6\n", "", true, ["-b", "-r", cmrb.path, dmrb.path]) end + +assert('String#split still works when mruby-regexp is loaded') do + # The regexp-aware override in mruby-regexp/mrblib/string_regexp.rb used to + # replace the C-defined String#split, leaving its `return super if ...` + # fast paths with no method to delegate to (NoMethodError). Now the + # override delegates via `__split`, an alias of the original C method + # installed in mrb_mruby_regexp_gem_init before mrblib runs. + assert_mruby(%Q(["a", "b", "c"]\n), "", true, + ["-e", 'p "a,b,c".split(",")']) + assert_mruby(%Q(["abc", "abc", "abc"]\n), "", true, + ["-e", 'p "abc abc abc".split']) + assert_mruby(%Q(["hello", "world"]\n), "", true, + ["-e", 'p "hello world".split(/\s+/)']) +end diff --git a/mrbgems/mruby-regexp/mrblib/string_regexp.rb b/mrbgems/mruby-regexp/mrblib/string_regexp.rb index f1f15f26a..e15e507a3 100644 --- a/mrbgems/mruby-regexp/mrblib/string_regexp.rb +++ b/mrbgems/mruby-regexp/mrblib/string_regexp.rb @@ -1,4 +1,9 @@ class String + # Capture the C-defined String#split under `__split` before the override + # below replaces it, so the override can delegate non-regexp patterns + # back to the core implementation. + alias __split split + def match(re, pos = 0) re = Regexp.new(re) if re.is_a?(String) re.match(self, pos) @@ -59,10 +64,14 @@ class String end end + # Regexp-aware split. Falls back to the C-defined split (aliased as + # `__split` in mrb_mruby_regexp_gem_init before this override loads) for + # nil or simple-string patterns; converts string-with-backslash to a + # Regexp and handles regexp patterns in Ruby. def split(pattern = nil, limit = -1) - return super if pattern.nil? + return __split(pattern, limit) if pattern.nil? if pattern.is_a?(String) - return super if pattern.length == 1 || !pattern.include?('\\') + return __split(pattern, limit) if pattern.length == 1 || !pattern.include?('\\') pattern = Regexp.new(Regexp.escape(pattern)) end result = []