The Crystal Programming Language Forum

Rename `Object#try(&block)` to `Object#not_nil?(&block)`

#try(&block)'s use case, currently, is to do something only if the object is not nil. To that end, #not_nil?(&block) seems to me to be more a more intuitive name.

We already have #not_nil! and #nil?. So we could add #not_nil? which would be the inverse of #nil?, and #not_nil?(&block) as a replacement for #try(&block):

class Object
  # ...
  def not_nil?
    !nil?
  end
  # ...
  def not_nil?
    yield self
  end
  # ...
end

struct Nil
  # ...
  def not_nil?(&block)
    self
  end
  # ...
end

Maybe it’s just me, but in the face of the nils and not nils, try seems to be the odd one out.

Of course, this means breaking changes and more work; I don’t know if it’s worth it?

Related?: #6600

I don’t think a rename is worth it at this point. This will cause a massive breaking change for no good reason.

By the way, we copied the try name from ActiveSupport: https://guides.rubyonrails.org/active_support_core_extensions.html#try

1 Like

Also, Object#not_nil?(&block) looks like a method that returns a boolean, not a method that returns the result of the block (or nil). For example, 1.try { |n| n + 2 } returns 3, not true or 1 (to return 1, you’d use Object#tap).

Object#not_nil? is like asking the Object “is it not nil?” which should return a boolean type.

2 Likes

Cc: @andraantariksa

That’s not definite. There are methods in the standard library with a ? suffix that return a nilable value, not a boolean. A few examples:

  • Enumerable#[]?
  • Enumerable#max?
  • Enumerable#min?

The general conventions seems to be that a ? suffix is used for methods that return a boolean, but also for ones that return a nilable object.

1 Like

That’s understandable. However, this came to mind whenever I’ve had to call a #try, so I thought I should bring it up.