Closed3

Rubyのエラー表示でbackslashがエスケープされる

pockepocke

all-rubyを試すと、Ruby 2.7からエラーの表示が変わっていて、バックスラッシュがエスケープされるようになっていた。

$ docker run -it --rm rubylang/all-ruby env ALL_RUBY_SINCE=1.8 ./all-ruby -e "\\".foo
ruby-1.8.0            -e:1: undefined method `foo' for "\\":String (NoMethodError)
                  exit 1
...
ruby-1.8.7-p374       -e:1: undefined method `foo' for "\\":String (NoMethodError)
                  exit 1
ruby-1.9.0-0          -e:1:in `<main>': undefined method `foo' for "\\":String (NoMethodError)
                  exit 1
...
ruby-2.3.0-preview1   -e:1:in `<main>': undefined method `foo' for "\\":String (NoMethodError)
                  exit 1
ruby-2.3.0-preview2   -e:1:in `<main>': undefined method `foo' for "\\":String (NoMethodError)
                      Did you mean?  fork
                  exit 1
ruby-2.3.0            -e:1:in `<main>': undefined method `foo' for "\\":String (NoMethodError)
                  exit 1
...
ruby-2.6.0-rc2        -e:1:in `<main>': undefined method `foo' for "\\":String (NoMethodError)
                  exit 1
ruby-2.6.0            -e:1:in `<main>': undefined method `foo' for "\\":String (NoMethodError)
                      Did you mean?  for
                  exit 1
...
ruby-2.6.8            -e:1:in `<main>': undefined method `foo' for "\\":String (NoMethodError)
                      Did you mean?  for
                  exit 1
ruby-2.7.0-preview1   -e:1:in `<main>': undefined method `foo' for "\\\\":String (NoMethodError)
                      Did you mean?  for
                  exit 1
...
ruby-2.7.4            -e:1:in `<main>': undefined method `foo' for "\\\\":String (NoMethodError)
                      Did you mean?  for
                  exit 1
ruby-3.0.0-preview1   -e:1:in `<main>': undefined method `foo' for "\\\\":String (NoMethodError)
                  exit 1
...
ruby-3.0.2            -e:1:in `<main>': undefined method `foo' for "\\\\":String (NoMethodError)
                  exit 1

https://bugs.ruby-lang.org/issues/15497 多分これの影響。

バックスラッシュをエスケープしているのは、制御文字をバックスラッシュでエスケープして書いた場合と、バックスラッシュそのものを区別できるように、という意味かなあ。

pockepocke
diff --git a/eval_error.c b/eval_error.c
index 98b8a22485..0b4a88ed52 100644
--- a/eval_error.c
+++ b/eval_error.c
@@ -103,10 +103,6 @@ write_warnq(VALUE out, VALUE str, const char *ptr, long len)
                     rb_write_error2(buf, snprintf(buf, sizeof(buf), "\\x%02X", c));
                 }
             }
-            else if (c == '\\') {
-                rb_write_error2(beg, ptr - beg + 1);
-                beg = ptr;
-            }
         }
         if (ptr > beg) {
             if (beg == RSTRING_PTR(str) && olen == RSTRING_LEN(str))

こういうパッチをあてれば例外の表示でバックスラッシュがエスケープされなくなる、がそれで良いのか

このスクラップは2021/07/18にクローズされました