April 21, 2016 by Daniel P. Clark

Use Ruby’s Refinements Anywhere With An Anonymous Class

For a long time I’ve been looking for a way to use Ruby’s refinements without building a class & method setup and then instantiating an instance of the class just to use it. And now I’ve finally found a solution.

The best work around I’ve found for accessing values outside the class wood be constants (preferable over global vars). If you wanted to take the extra effort your can have a constant be an instance of Binding to grab the local variables.

I’ve put in a feature request for Ruby’s using method to take a block syntax and allow access to local variables Feature Request #12281. So this would bring back the convenience of local variable access available in Ruby 2.2.3.

Example of Refinement Use in Just One Method

If you use the Object#bv method defined above you may use kind of a dynamic constant variable to grab the local variable.

Antipattern

But at this point we’ve gone too far to bend against the design of how a refinement is used (and other Ruby design principles) and it would be simpler to just write the refinement as intended by design.

Pattern

As you can see this is a lot of class wrapper just to refine one little thing in a method. So I really hope my feature request get’s accepted for Ruby and we can simplify the use of refinements anywhere and still stick to a strict lexical scope.

Summary

Refinements are great but they still have a way to go (see: Ruby Refinements – Not quite ready for production).  At the time of this writing the Ruby core team seams really focused on just patch/bug related updates and I haven’t seen them accept a new feature since before the release of 2.3.0.  But once there next release version is out I’m hopeful for newer and improved features for the language 🙂 .

I’ve been into programming in the Rust language a lot lately and there use of implementations on types works in the same manner as Ruby’s refinements without all the extra hassle.  In Rust where ever you write use my_crate::MyTrait; it adds the functionality to a specific object type just like Ruby’s refinements and it’s available within whatever scope you put it.  I’m hoping Ruby heads more in this direction.  I’m sure I’ll be writing about Rust soon so look forward to it!

As always I hope you found this educational and enjoyable!  Please feel free to comment, share, subscribe to my RSS Feed, and follow me on twitter@6ftdan!

God Bless!
-Daniel P. Clark

Image by solarisgirl via the Creative Commons Attribution-ShareAlike 2.0 Generic License.

#anonymous#block#class#convenient#refinement#ruby#scope#short