Object#with(**args) method is not part of the Ruby standard library. Thanks to Rails, it’s a convenience method added to the
Object class to manage object states.
Saving the value of an attribute, setting a new value, and then restoring the previous value in an ensure clause is a fairly popular pattern in Ruby, particularly in testing or in api calls
This is a common and popular pattern as everything works fine in this pattern but sometimes when we have a code block before the
# perform posts testing which raises an exception then
user.verified is set to old_value due to the ensure block
# perform posts testing will have
user.verified with old value instead of
Object#with helps to streamline and elegantly improve this technique. It is an addition to the Ruby Object class that offers a simpler method of managing object states.
With the upcoming version of Rails, we can temporarily change one or more attributes of an
Object#with and guarantee that they automatically revert to their initial values even if an error arises while the block is being executed.
#with method isn’t available on Nil class
and other common immediate types because immediate values are immutable
and do not support method additions or removals, applying the
with method to them doesn’t work as expected. It may lead to errors or unexpected behaviour.
For example, we have Integer
32 and if we try to use with method on top of the Integer like
32.with(args) to change its state temporarily, it won’t work because we cannot modify an immediate value in this way.
Due to this reason,
#with is not available on
Object#with simplifies state management of Ruby object, making our code cleaner, more readable, and less error-prone.
Whether we’re writing tests, working with APIs, or configuring our application.