My 2 cents.
I always had the feeling people complaining about `RegExp.$1` and friends
never really used them.
For instance, your example:
```js
/(a)/.exec('a')
Object.keys(bar)
RegExp.$1
```
might have side effects but it's also made up and, I believe, not a
real-world concern.
If you use `re.exec` you address it, otherwise you go `re.test` while if
you use `re.test` you (or at least *me*) are aware of possible side effects
and will use the `RegExp.$1` or other property *instantly* after.
Following just a simple example:
```js
if (/^item-(\d+)$/.test(id)) {
let num = parseInt(RegExp.$1, 10);
// the rest of the code
}
```
I'm not saying these properties are cool, always safe, or anything, I'm
just saying there are few useful cases for them.
However, while I agree the problem is that these modify the globally shared
constructor, I also think that having these magic properties available in a
subclass only, would be probably the key to solve pretty much all problems
described in that page.
```js
reg.exp = class extends RegExp {};
function reg(source, ...flags) {
return typeof source === 'string' ?
new reg.exp(...[source, ...flags]) :
new reg.exp(source.source, source.flags);
}
if (reg(/^item-(\d+)$/).test(id)) {
let num = parseInt(reg.exp.$1, 10);
// the rest of the code
RegExp.$1 === reg.exp.$1; // false
// the extended RegExp didn't modify
// the global RegExp
}
```
Of course this would still suffer same, or very similar, problems in case
`re.class` is exported as module and consumed by many different libraries,
but I would be surprised if subclassing `RegExp` will create a limited
subset or, at least, I wouldn't call that an extend.
After all, if "safe" is the main concern, writing `class SRegExp extends
RegExp {}` on top of a module that uses RegExp in various ways doesn't look
like a big piece of extra code to write, it's like a function declaration
and it will make your code immune from global RegExp gotchas.
Or ... doesn't it?
Best Regards
On Tue, Apr 26, 2016 at 7:20 PM, Claude Pache <[email protected]>
wrote:
> Hi,
>
> About the bad old nonstandard RegExp functionalities:
>
> * `RegExp.prototype.compile()` — currently in Annex B;
> * `RegExp.$1`, `RegExp.leftContext`, etc. — currently unspecced.
>
> Although we could probably not get rid of them for plain regexps, I think
> it is a good idea to disable them for proper subclasses of RegExp (e.g.,
> `class MyRegExp extends RegExp {}`).
>
> Basically, the reason is that these methods break encapsulation (they
> operate on the raw regexp), leading to potential bugs when using them.
> Moreover `RegExp.$1` and friends have the additional troublesome property
> of relying on a global state that could be unexpectedly modified. For
> concrete examples of what could go wrong, see the
> subclass-restriction-motivation.md subpage in the proposal linked below.
>
> Here is a link to a possible specification for the regexp statics
> (RegExp.$1, ...), that includes the disabling of bad legacy features for
> proper subclasses of RegExp (and for some edge-cases around cross-realm
> interactions):
>
> https://github.com/claudepache/es-regexp-legacy-static-properties
>
> What do you think? Are implementations willing to try?
>
> —Claude
>
>
> _______________________________________________
> es-discuss mailing list
> [email protected]
> https://mail.mozilla.org/listinfo/es-discuss
>
>
_______________________________________________
es-discuss mailing list
[email protected]
https://mail.mozilla.org/listinfo/es-discuss