Ohai Fellow Rubyists!
This week we’re going to look at using custom setter methods in your Ruby class initializers to do any custom logic before setting instance variables. I just had to do this last week for a gem I’m writing. Here’s a quick snippet. Read on for the full explanation.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
|
Background
Recently, I’ve been working on a gem to send Jenkins build status to our Stash git server as part of our CD pipeline.
This gem, ‘stash_notifier’, takes job_status
as an argument in its class initializer. At first I just set the instance variable directly like this:
1 2 3 4 5 6 |
|
But then I realized I really should upcase
the job_status
per the Atlassian SDK docs. Plus I wanted to check the job_status
parameter the user passed into the StashNotifier.new
method to make sure it was valid. To solve this I wrote a custom setter.
Custom Setters
Ruby includes some nice helper methods, attr_reader
, attr_writer
, and attr_accessor
to create setters and getters for you. These just set or return the instance variables and don’t allow for any customization. If you want to do some validation or modify the passed-in parameters, define a custom setter like this:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
|
We first define an attr_reader
to have Ruby create the getter for us. We’ll define the setter separately so we can add some of our own logic.
Instead of setting the job_status
instance variable in our class initializer, we call the custom setter, job_status=
. By defining it as a method with a trailing =
, we make it a setter. We prepend it with self.
to specify that it’s a method and not a local variable.
This setter method will be called during initialization, and anytime we do this:
1 2 |
|
By calling the custom setter in the class initiaize method, we make sure that our custom setter is always called, both at initialization time and whenever we set the job_status
“property” on our class instance, making our solution DRY.
Summary
I hope you’ve found this useful. It took quite a bit of Googling for me to find out this little tidbit. Here are a couple of links I found helpful during my research: