March 9, 2015 by Daniel P. Clark

Ruby: Actionable Meta

The more you program the more likely you will need to change a string to the object the string represents. For example you may have a string with a mystery class name in it the you need to call methods on. Lets go a step further, lets say the method you need to call on it is also a string. Well the first thing most will learn when looking into doing this is normally eval. eval turns your strings into ruby code and evaluates it right in place.

So this is fine for now. It works. Lets look at an eval inside a method where the first object is not a string.

Notice in my eval I didn’t interpolate h with #{}. The reason is because of scope; the method h is already the Object we want to run a command on. But the m variable was still a String that we wanted to run as a command.

Now something that I was unaware of for a long time was that you can attach methods right on the end of eval() as if you were writing the method right on the Object that eval produces.

This will get you a long way. But you may have heard that it’s dangerous to use eval when you don’t know what might be eval‘d. So how else might we achieve this same flexibility of meta execution?

Now enters the send command.  The send command will allow you to send either a Symbol or a String as a command to execute on the object you call send on. That; and you can still chain commands onto the resulting Object just like normal.

You might say: “Well that’s cool. But what about the case where the object you want is a string?” Yes if we’re avoiding eval we’ll need to use another option; as send will be invoking a method on the String instance and not the Object it is meant to represent. And for that, Ruby has an answer: Kernel.get_const

In both of these examples it was the string “Array” that was turned into the constant (class Array) from where we were then able to invoke our methods on.

In Rails there is a method available on String objects that will do this for you: constantize

This make for a much cleaner experience for all your meta-programming needs.

Summary

All the tools you need are right at your finger tips. Practice, experiment, and brain storm. There are countless ways you can take advantage of this. I’ve come across a couple of instances where the use of lambda came in handy for connecting and evaluating Rails models that belonged to one another. So keep these handy ^_^

Hope you enjoyed this! Please feel free to comment, share, subscribe to my RSS Feed, and follow me on twitter @6ftdan!

God Bless!
-Daniel P. Clark

Image by Jason Sweeney via the Creative Commons Attribution-NonCommercial-ShareAlike 2.0 Generic License.

#constantize#eval#get_const#Kernel#lambda#meta#meta-programming#rails#ruby