Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

Already on GitHub? Sign in to your account

Using REPL breaks RegExp.[$1..$9] #4088

Closed
pennig opened this Issue Oct 6, 2012 · 7 comments

Comments

Projects
None yet
6 participants

pennig commented Oct 6, 2012

$ node
> "foo".match(/(\w)/);
[ 'f',
  'f',
  index: 0,
  input: 'foo' ]
> RegExp.$1
'RegExp.$1'

I expected 'f'. Looks like the REPL is executing its own RegExp, overwriting the previous values.

Ok, same does Google Chrome Console. This is a bug, but seriously, anybody keen on this in REPL or console?

(function(){ "foo".match(/(\w)/); console.log(RegExp.$1) })(); // works fine.

I don't know how to resolve this smart way... Fix is possible of cource, but copy of $1, $2, $3.. static vars on the walk before and after every REPL eval..

Owner

bnoordhuis commented Oct 6, 2012

It's fairly simple to fix but it looks really ugly...

diff --git a/lib/repl.js b/lib/repl.js
index 361745f..fe3077c 100644
--- a/lib/repl.js
+++ b/lib/repl.js
@@ -104,9 +104,14 @@ function REPLServer(prompt, stream, eval_, useGlobal, ignoreUndefined) {

   self.useGlobal = !!useGlobal;
   self.ignoreUndefined = !!ignoreUndefined;
+  self._saved = [];

   self.eval = eval_ || function(code, context, file, cb) {
     var err, result;
+
+    // restore RegExp.$1 to RegExp.$9
+    /^\u0000(.*)\u0000(.*)\u0000(.*)\u0000(.*)\u0000(.*)\u0000(.*)\u0000(.*)\u0000(.*)\u0000(.*)$/.test(self._saved.join('\u0000'));
+
     try {
       if (self.useGlobal) {
         result = vm.runInThisContext(code, file);
@@ -116,6 +121,11 @@ function REPLServer(prompt, stream, eval_, useGlobal, ignoreUndefined) {
     } catch (e) {
       err = e;
     }
+
+    for (var i = 1; i <= 9; ++i) {
+      self._saved[i] = RegExp['$' + i];
+    }
+
     cb(err, result);
   };

You have to use a regular expression to restore the registers because RegExp.$1 and friends are not assignable.

isaacs commented Oct 7, 2012

Huh. Well, that's clever. Nice, @bnoordhuis.

But I don't think it's really justified. Repls are always a little
magical. -1 on this unless a lot more people complain about it.

On Sat, Oct 6, 2012 at 4:49 PM, Ben Noordhuis notifications@github.comwrote:

It's fairly simple to fix but it looks really ugly...

diff --git a/lib/repl.js b/lib/repl.jsindex 361745f..fe3077c 100644--- a/lib/repl.js+++ b/lib/repl.js@@ -104,9 +104,14 @@ function REPLServer(prompt, stream, eval_, useGlobal, ignoreUndefined) {

self.useGlobal = !!useGlobal;
self.ignoreUndefined = !!ignoreUndefined;+ self._saved = [];

self.eval = eval_ || function(code, context, file, cb) {
var err, result;++ // restore RegExp.$1 to RegExp.$9+ /^\u0000(.)\u0000(.)\u0000(.)\u0000(.)\u0000(.)\u0000(.)\u0000(.)\u0000(.)\u0000(.*)$/.test(self.saved.join('\u0000'));+
try {
if (self.useGlobal) {
result = vm.runInThisContext(code, file);@@ -116,6 +121,11 @@ function REPLServer(prompt, stream, eval
, useGlobal, ignoreUndefined) {
} catch (e) {
err = e;
}++ for (var i = 1; i <= 9; ++i) {+ self._saved[i] = RegExp['$' + i];+ }+
cb(err, result);
};

You have to use a regular expression to restore the registers because
RegExp.$1 and friends are not assignable.


Reply to this email directly or view it on GitHubhttps://github.com/joyent/node/issues/4088#issuecomment-9203592.

Is anywhere "collection of RELP side effects?"

There might be some other clever ways to fix this (I'm thinking give the REPL its own RegExp object so that captures get set on that distinct one, rather than the global one). Another one might be to remove the use of RegExp in the parts that are causing the problem. I haven't really looked into the problem yet...

@TooTallNate If this will be possible +1, but I'm afraid not.

Given lack of activity, closing this. The solution to restore is pretty neat, though.

@vkurchatkin vkurchatkin referenced this issue in nodejs/node Jan 24, 2015

Closed

repl: repl clobbers RegExp.$1 #597

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment