Follow

Is there ever a good time to define a custom `!` method on an object? Seems like setting up a footgun for people relying on the truthy/falsiness in a boolean expression.

class Thing; def !; true; end; end
my_thing = Thing.new

do_thing if my_thing# executes
do_thing if !my_thing # executes
do_thing unless my_thing # does not execute

Chatted about this with a couple local Ruby programmers and the consensus seems to be "probably not."

@jsrn Doesn't seem a very Ruby-ish way to do it. Wouldn't it be more normal to define a present? or has_data? method, or whatever it is you want? So `do_thing if my_thing.has_data?` and so on?

@johnpettigrew Yeah, absolutely!

I'm asking about ! less in terms of "is this idiomatic" and more "I'm surprised this is possible, does anyone have a solid use case" :)

@jsrn Heh. My brain tends to say, "if it's not idiomatic then there is no use case". 😛

@jsrn
I think the use case is probably: "if my object can be seen as boolean and I need to implement NOT". Although I'm struggling to think of an example…
@johnpettigrew

@andy_twosticks Yep! I can see the idea, but I try to come up with concrete examples and I'm drawing a blank.

@jsrn Maybe an immutable helper class that you instantiate just to answer a question?
isfoo = IsFooHelper.new(myobj)
raise "oh no" if !isfoo

@jsrn only if the class is a custom Boolean-like class, then one would expect `!obj` to behave accordingly.

@postmodern Good shout. First thing that springs to mind for me is e.g. reading a CSV and having a class that reads a column full of 'Yes'/'No' or similar and converts to boolean-esque objects.

Do you have any examples of when a custom boolean-like class has been useful for you?

@jsrn for CSV/etc I'd probably just map them to native true/false.

The other example I can think of off the top of my head is a DSL where you'd need a custom True/False object, that perhaps provides additional methods or could emit code?

Sign in to participate in the conversation
Ruby.social

A Mastodon instance for Rubyists & friends