空の正規表現リテラル(!! //)のdouble-notはfalseですが、これは解析エラーですか?[複製]

Aug 23 2020

Rubyでは、のみfalsenilfalseyです。他のすべては真実です。2つのnot演算子を使用して、オブジェクトの真実性を確認できます。

!!false   # false
!!nil     # false
!![]      # true
!!{}      # true
!!''      # true
!!0       # true

しかし、空の正規表現リテラル//は誤りであることがわかりましたが、変数としては真実です!:

!!//        # false!
not not //  # false
x = //
x.class     # Regex
!!x         # true

これはパーサーの癖だと思います。パーサーに何をしているのかを尋ねるにはどうすればよいですか?

回答

2 benjessop Aug 23 2020 at 02:32

これは、空の正規表現リテラルだけでなく、すべての正規表現リテラルに適用できます。

!!/(.*)/
=> false

x = /(.*)/
!!x
=> true

最初、これは正規表現の構築方法に問題があるように見えました

!!Regexp.new('')
=> true
x = Regexp.new('')
!!x
=> true
!!//.freeze
=> true

しかし、深く掘り下げると、これが原因のようです。

!!//
=> false
$_ = 'b'
!!//
=> true

'$ _'をnilに戻すと、結果がリセットされます。の値$_は、Kernel.readlineまたはKernel.get兄弟から設定されます。新しいコンソールの場合:

Kernel.readline
a
"a\n"
!!//
=> true

したがって、でRegexpオブジェクトをインスタンス化する//と、の値と一致するように見えます。$_

1 Andrés Aug 23 2020 at 00:59

正直なところ、100%確信はありませんが、私の考えでは、実行するとRubyが次のことを実行します。 !!x

puts !!// # this is doing a phantom .match(nil), like below, so, returns false
x = //
puts !!x.match(nil)