2

I want to create a class Nilly to obtain a "pseudo-nil" object, but I need it to be evaluated as boolean false.

e.g.:

class Nilly; end

n = Nilly.new

puts n ? 'true' : 'false'    #=>  I want false here

How can I do that?

P.S.: I tried to do class Nilly < NilClass, but I coudn't use the new method (it was stripped out in NilClass).

Chris Kooken
  • 32,730
  • 15
  • 85
  • 123
Sony Santos
  • 5,435
  • 30
  • 41
  • There is no instance (thankfully :-) –  Oct 14 '11 at 19:02
  • 1
    There are similarities between the two questions, but they seem different enough to merit keeping both of them. That question is about how to make an objects that acts like nil, this is how to make one that is _falsy_. Each of these questions can have answers unique to it. – Wayne Conrad Mar 05 '14 at 20:43

2 Answers2

1

Boolean logic in Ruby ONLY allows nil and false to be falsy

Everything else is truthy.

There is no way to do this.

May I ask why you want this? What is special about your Nilly class?

I suggest you just call it a different way.

class Nilly
  def nil?
    true
  end
end

And use this in your logic

puts n.nil? ? 'false' : 'true'
Matthew Rudy
  • 16,724
  • 3
  • 46
  • 44
  • 1
    In [this question](http://stackoverflow.com/questions/7235322/nils-and-method-chaining), the author doesn't want to redefine `NilClass#method_missing`, for that would be very intrusive. So, I was wondering about to use an alternative class to do that. – Sony Santos Oct 14 '11 at 18:58
  • You should look at `try` defined in `ActiveSupport`. `something.try(:a_method)` returns `nil` for `nil`, or calls `something.a_method` otherwise. – Matthew Rudy Oct 14 '11 at 19:02
  • In fact, if I need only a class which `method_missing` returns `nil`, _and_ if I don't need to evaluate it as boolean, it doesn't need to inherit `NilClass`. I'll think about it. – Sony Santos Oct 14 '11 at 19:15
  • 1
    Yeah, I think the answer is not to make a `magic nil`, but to approach your problem in a different way. – Matthew Rudy Oct 14 '11 at 19:20
0

Override the new method:

class Nilly < NilClass
  def Nilly.new
  end
end

n = Nilly.new
puts n ? 'true' : 'false'    #=>  I want false here

Unlike the previous two solutions, this does exactly what you want. n actually evaluates as nil, without the need to test with a nil? method. The to_s solution only works because you are putsing it, which implicitly calls to_s.

p4010
  • 943
  • 7
  • 19
  • Damn, I always come too late... – p4010 Oct 14 '11 at 18:58
  • 2
    you're just returning `nil`. In which case you may as well ignore the `Nilly` definition, and say `n = nil` – Matthew Rudy Oct 14 '11 at 19:08
  • Nope: this does exactly what the author wants. If I read it right he wants a class "to be evaluated as boolean false". To do that, the class must be a NilClass child or a FalseClass child, *tertium non datur*. Incidentally, I am **not** returning a `nil`. – p4010 Oct 14 '11 at 19:13
  • you are returning a nil. please try your code. n is EXACTLY nil. It is not an instance of Nilly. – Matthew Rudy Oct 14 '11 at 19:19
  • 1
    Ruby 1.8.7: `n.inspect` returns "nil". I opened `Nilly` and `def to_s; 'nilly'; end`, but `n.to_s` returns "". – Sony Santos Oct 14 '11 at 19:21