Inspired by previous HN discussion here: https://qht.co/item?id=943597 which discussed how you go about programmatically creating methods in Ruby. This post provides more of the why. (Short version: get more stuff done faster, go home early!)
Unfortunately by the time I got the syntax highlighting working it was already 3:15 AM, so it is unlikely I'll have much to say in the comments. Enjoy the article!
Another way to do this (and one that Rails makes extensive use of internally) is to override method_missing in your object, which gets called as a "last resort" whenever ruby can't find a method of a particular name. Inside this method you can check to see if the method being called matches one of the keys of your hash, and if so do what you need. This is a little bit more "meta" (if there is such a thing) than your example because the getters/setters for each of the options are never actually defined on the class, not even at runtime.
I'd argue that using define_method is a far better solution, for a few reasons.
First, you also should override respond_to? as well when using method_missing so that other people's code that relies on respond_to? doesn't break in mysterious ways. You have to make sure that both of these methods work consistently. This provides a few chances to break things. If someone else is metaprogramming and relying on instance_methods or methods, you would have to override those too to make things work consistently.
Also, using method_missing doesn't let you use alias_method_chain or several other metaprogramming techniques at all. For instance, since ActiveRecord models use method_missing to generate attribute accessors and dynamic finders, it's impossible to use alias_method_chain or something like it on them. You have to rely on ActiveRecord's unique and different kind of metaprogramming methods (alias_attribute, among others) which is, in my opinion, undesirable.
Finally, when using method_missing, you vastly limit your ability leverage inheritance or mixins at all. If you'd like to inherit from a class that relies on method_missing, it is impossible to use method_missing in that class without breaking behavior. It's also possible to define methods in mixins using define_method, while using method_missing in a mixin means it could stomp all over other mixins.
So, in conclusion, method_missing is something that I think should be considered generally harmful and a last resort. The original poster's use of define_method is more durable, less "magic", and a better option.
All excellent points. Sorry if my original comment wasn't clear -- I wasn't trying to say that method_missing is a better way to do it, just that it's a different way to accomplish the same thing.
But doesn't this prevent you from taking advantage of AR validations and form_helper stuff, which is precisely the stuff that patio11 is saying makes meta-programming most useful in this case?
Another minor security nit: when you dynamically add accessors to an AR class, you make it harder to control which accessors should be exposed to mass assignment (foo.update(params)).
It was thoughtful for you to bring security up at all, though.
Unfortunately by the time I got the syntax highlighting working it was already 3:15 AM, so it is unlikely I'll have much to say in the comments. Enjoy the article!