The Crystal Programming Language Forum

Object#presence

Although I’m used to Ruby’s presence I think I prefer to keep it in the String? realm only.

But something I think it might work at Object is a #nil_if (or something like that) that will, well, return nil if the block evaluates to true, and self otherwise.

That way patterns like the following can be allowed.

array_expr.nil_if(&.empty) || default_array

That way 0, [] or whatever value is wanted to be treated as blank can be definied per need explicitly.

2 Likes

I actually agree with this, but not for the reason you might think. :slightly_smiling_face:

Is array_expr.nil_if(&.empty?) the same as !array_expr.empty? (except false vs nil)?

Almost. Having Object#nil_if and Nil#nil_if is what will allow you to deal with nil and whatever value matches the block predicate in a neat way IMO.

1 Like

I personally don’t see a compelling reason to introduce it, and I think the burden of proof goes in that direction. Erring on the side of not adding something is much more maintainable than the other way around. I do agree that it seems weird to have this thing in only String that also leaks into Nil, but I still don’t think that’s a strong enough argument to implement it widely in the standard library.

My main hang-up with this is that it makes the code potentially (and barely) more readable for Ruby devs at the expense of readability for people who don’t have that background (like me). Your example,

my_var = my_var.presence || ["default", "array"]`

isn’t very clear to me. If this were introduced (and I hadn’t read this thread), the following inner monologue seems pretty likely to me: ‘“Presence”? What does that mean? That it’s “there”? Well, if it isn’t “there” already, wouldn’t it just be Nil? Why not just use #nil??’ Obviously, “this syntax doesn’t make perfect sense to me” isn’t the most persuasive argument, but my point is that a semantic that you’re used to isn’t necessarily one that most people will find intuitive if they don’t have your background.

4 Likes

I do think this would be very useful. If introduced would we want to remove or deprecate String | Nil#presence ?
Happy to make a pull request

array = ["default"] unless array || !array.empty?
vs
array = ["default] if array.nil_if &.empty?

For me are quite similar. The goal is not always to have the shortest lines available. Here having a new method, extending the API for all objects, does not worth the few chars saved.

1 Like

I think it’s useful if we deprecated the use of String#presence
which would be adding a few chars to that case but providing a generic pattern moving forward

1 Like