4 ms·
Great article, thanks. Another way to do this (and one that Rails makes extensive use of internally) is to override method_missing in your object, which gets c
by cmatthias 17y ago
Great article, thanks.
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.
- stephenjudkins 17y agoI'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.
- cmatthias 17y agoAll 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.
- stanleydrew 17y agoBut 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?