Il doppio non di un letterale regex vuoto (!! //) è falso, è un errore di analisi? [duplicare]

Aug 23 2020

In Ruby, solo falsee nilsono false; tutto il resto è vero. Puoi utilizzare due notoperatori per verificare la veridicità di un oggetto:

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

Ma poi ho scoperto che il letterale vuoto-regex //è falso, ma come variabile, è vero!:

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

Penso che questa sia una stranezza del parser. Come posso chiedere al parser cosa sta facendo?

Risposte

2 benjessop Aug 23 2020 at 02:32

Questo non è applicabile solo al letterale regex vuoto, ma piuttosto a tutti i letterali regex;

!!/(.*)/
=> false

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

All'inizio questo sembrava essere un problema con il modo in cui viene costruita la regexp

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

Ma scavando più a fondo, questa sembra essere la causa:

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

L'impostazione di '$ _' su zero ripristinerà il risultato. Il valore per $_è impostato da Kernel.readlineo Kernel.getfratelli. In una nuova console:

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

Quindi istanziare un oggetto Regexp con //sembra confrontarlo con il valore di$_

1 Andrés Aug 23 2020 at 00:59

Ad essere onesti, non ne sono sicuro al 100%, ma la mia idea è che Ruby stia facendo la prossima cosa quando corri !!x

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