Practical Metaprogramming with Ruby: Storing Preferences
kalzumeus.com
kalzumeus.com
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.
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.
It was thoughtful for you to bring security up at all, though.