tobyink/p5-type-tiny

An is_Foo where Foo is a StrMatch based type returns the capture if the RE captures

djerius opened this issue · 6 comments

Howdy.

Here's some test code:

use v5.10;

package Types {
    use Type::Library -base, -declare => ( qw( FilterName ) );
    use Types::Standard 'StrMatch';
    use Type::Utils -all;

    declare FilterName, as StrMatch( [qr/\A( [[:alpha:]_][\w-]*  )\z/x] );
}

say  Types::is_FilterName( 'foo-bar' );

Note the capture in the regexp.
Here's the output:

perl foo.pl
foo-bar

I expected a truthy value, not the capture from the RE. Note that forcing the return of is_FilterName into scalar context, or removing the capture makes it work (i.e. returns a truthy value).

Interesting. Not sure whether this is a bug or a feature.

🤔

Thanks!

I don't think your initial example was especially harmful, but if you were capturing the string "0", that could get bad.

Yeah. Hadn't thought of that; it'd be major source of confusion. Normally I'd not have captures in this context, but the regexp is being reused from elsewhere. I don't think there's a "turn captures" off regexp modifier. Maybe I should submit a pre-RFC for that...

A turn off captures modifier would be pretty nice in general. I'd love to be able to use (...) freely as a grouping mechanism in regexp. (?:...) is so much more verbose.

The n modifier was introduced back in 5.22

Prevent the grouping metacharacters () from capturing. This modifier, new in 5.22, will stop $1, $2, etc... from being filled in.
... This is equivalent to putting ?: at the beginning of every capturing group.
... /n can be negated on a per-group basis. Alternatively, named captures may still be used.