[ruby/strscan] StringScanner#captures: Return nil not "" for

unmached capture
(https://github.com/ruby/strscan/pull/72)

fix https://github.com/ruby/strscan/issues/70
If there is no substring matching the group (s[3]), the behavior is
different.

If there is no substring matching the group, the corresponding element
(s[3]) should be nil.

```
s = StringScanner.new('foobarbaz') #=> #<StringScanner 0/9 @ "fooba...">
s.scan /(foo)(bar)(BAZ)?/  #=> "foobar"
s[0]           #=> "foobar"
s[1]           #=> "foo"
s[2]           #=> "bar"
s[3]           #=> nil
s.captures #=> ["foo", "bar", ""]
s.captures.compact #=> ["foo", "bar", ""]
```

```
s = StringScanner.new('foobarbaz') #=> #<StringScanner 0/9 @ "fooba...">
s.scan /(foo)(bar)(BAZ)?/  #=> "foobar"
s[0]           #=> "foobar"
s[1]           #=> "foo"
s[2]           #=> "bar"
s[3]           #=> nil
s.captures #=> ["foo", "bar", nil]
s.captures.compact #=> ["foo", "bar"]
```

https://docs.ruby-lang.org/ja/latest/method/MatchData/i/captures.html
```
/(foo)(bar)(BAZ)?/ =~ "foobarbaz" #=> 0
$~.to_a        #=> ["foobar", "foo", "bar", nil]
$~.captures #=> ["foo", "bar", nil]
$~.captures.compact #=> ["foo", "bar"]
```

* StringScanner#captures is not yet documented.
https://docs.ruby-lang.org/ja/latest/class/StringScanner.html

https://github.com/ruby/strscan/commit/1fbfdd3c6f
This commit is contained in:
NAITOH Jun 2024-01-13 06:22:32 +09:00 коммит произвёл Sutou Kouhei
Родитель 0610f555ea
Коммит 338eb0065b
2 изменённых файлов: 13 добавлений и 9 удалений

Просмотреть файл

@ -1243,10 +1243,10 @@ strscan_size(VALUE self)
* If nothing was priorly matched, it returns nil.
*
* s = StringScanner.new("Fri Dec 12 1975 14:39")
* s.scan(/(\w+) (\w+) (\d+) /) # -> "Fri Dec 12 "
* s.captures # -> ["Fri", "Dec", "12"]
* s.scan(/(\w+) (\w+) (\d+) /) # -> nil
* s.captures # -> nil
* s.scan(/(\w+) (\w+) (\d+) (1980)?/) # -> "Fri Dec 12 "
* s.captures # -> ["Fri", "Dec", "12", nil]
* s.scan(/(\w+) (\w+) (\d+) (1980)?/) # -> nil
* s.captures # -> nil
*/
static VALUE
strscan_captures(VALUE self)
@ -1262,9 +1262,13 @@ strscan_captures(VALUE self)
new_ary = rb_ary_new2(num_regs);
for (i = 1; i < num_regs; i++) {
VALUE str = extract_range(p,
adjust_register_position(p, p->regs.beg[i]),
adjust_register_position(p, p->regs.end[i]));
VALUE str;
if (p->regs.beg[i] == -1)
str = Qnil;
else
str = extract_range(p,
adjust_register_position(p, p->regs.beg[i]),
adjust_register_position(p, p->regs.end[i]));
rb_ary_push(new_ary, str);
}

Просмотреть файл

@ -737,8 +737,8 @@ module StringScannerTests
def test_captures
s = create_string_scanner("Timestamp: Fri Dec 12 1975 14:39")
s.scan("Timestamp: ")
s.scan(/(\w+) (\w+) (\d+) /)
assert_equal(["Fri", "Dec", "12"], s.captures)
s.scan(/(\w+) (\w+) (\d+) (1980)?/)
assert_equal(["Fri", "Dec", "12", nil], s.captures)
s.scan(/(\w+) (\w+) (\d+) /)
assert_nil(s.captures)
end