2

In Ruby, only false and nil are falsey; everything else is truthy. You can use two not operators to check an object's truthiness:

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

But then I found that empty-regex literal // is falsey, but as a variable, it's truthy!:

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

I think this is a quirk of the parser. How can I ask the parser what it's doing?

ConvexMartian
  • 331
  • 2
  • 14

2 Answers2

2

This is not just applicable to empty regex literal, but rather all regex literals;

!!/(.*)/
=> false

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

At first this appeared to be an issue with the way the regexp is being constructed

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

But digging deeper, this appears to be the cause:

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

Setting '$_' back to nil will reset the outcome. The value for $_ is set from Kernel.readline or Kernel.get siblings. In a new console:

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

So instantiating a Regexp object with // appears to match it against the value of $_

benjessop
  • 1,729
  • 1
  • 8
  • 14
1

To be honest, I'm not 100% sure, but my idea is that Ruby is doing the next thing when you run !!x

puts !!// # this is doing a phantom .match(nil), like below, so, returns false
x = //
puts !!x.match(nil)
Andrés
  • 624
  • 7
  • 12