After a long confusing Ruby debate today at OpenRain on the merits of functional, Erlang-esque write-once-read-many variables, I’m going to step onto the podium and just say it… Ruby should get “final” or “const” variables in a similar semantic style to Java, except at runtime. Rather than ramble on for 12 paragraphs explaining exactly how this might work, read this fictitious Ruby code snippet instead. (Optional: Also check out the chapter on “final” in Hardcore Java.)
Final variables like this are really just an inline TDD mechanism.
Allowing local stack data to be constant provides no functional enhancements to the software, but alleviates the need for certain types of tests by using the compiler and/or runtime to assert certain memory is immutable. The “friend_best” method variant in the code snippet would obviously break most existing Ruby programs, but ups the bar for defensive programming by preventing many common bugs out-of-the-box while still providing support for traditional Ruby variables. At the very least we should have something like “friend_better”. Adding this information to the parse tree will also make it easier for IDEs to provide features more easily implemented for static languages.
TDD/BDD is in–no qualms about it–but we can make our code safer, cleaner and more concise by applying some of the lessons learned by our statically-typed language cousins over the last few decades.
2 replies on “What If Ruby Had Final Variables Like Java Or Erlang?”
I recently came to Ruby after developing with java for many years. I found your blog after searching for Ruby final variables because as of now I have an array of languages which I defined in my helper class. I have in several places duplicated this list to pair it down to determine which translations I am missing. I want to make this list final. I should be able to make this list final. It not being final is a threat to my applications stability and correctness. Any suggestions?
I’m not 100% sure I understand the situation, but this seems like it would be a great context for “final” variables to be utilized. If you’re primarily having issues debugging, you could try freezing the object to prevent unintended mutations after initial setup, or simply override the mutators causing havoc to raise exceptions. That’s not a solution I’d permanently leave in the code, but it at least helps for debugging purposes. HTH,
Preston