In several places in Rails (e.g., ActiveRecord `find_by_#{attr2}_and_#{att2}`
methods), you override `method_missing` to provide functionality. In all of
those places, you follow the sane approach of handling `respond_to?` as well as
actually defining the method body for future callers.
I've abstracted this logic out into a project called def_method_missing[1].
Examples:
class Foo
# regexp matchers yield the MatchData to the block, so you can modify the
method
# body based on the regexp
def_method_missing /bar/ do |match|
-> { match.pre_match }
end
# without a regexp matcher, the name of the method is passed to the block,
allowing
# you to decide whether or not to implement the method
def_method_missing do |name|
-> { name } if name.length == 4
-> { "bang!" } if name[-1] == '!'
end
end
foo = Foo.new
# regexp-based method_missing
foo.respond_to?(:bazbar) # => true
foo.bazbar # => "baz"
foo.methods.include? /bazbaz/ # => true
# arbitrary Ruby method_missing
foo.respond_to?(:wat) # => false
foo.respond_to?(:what) # => true
foo.what # => :what
foo.methods.include?(:what) # => true
foo.bang # => :bang # matches four-character method name
foo.bang! # => "bang!" # matches last-character bang
foo.wat! # => :wat! # matches four-character method name first
Is this something you'd be willing to consider including in ActiveSupport?
Obviously, I'll have to put the logic into its own Module to avoid polluting
default `Object`s and `Module`s. Plus documentation/tests. The current
implementation was just a concept I threw together a few months back and
promptly forgot about.
[1]: https://github.com/stouset/def_method_missing
--
You received this message because you are subscribed to the Google Groups "Ruby
on Rails: Core" group.
To view this discussion on the web visit
https://groups.google.com/d/msg/rubyonrails-core/-/ICy42NxOSOAJ.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to
[email protected].
For more options, visit this group at
http://groups.google.com/group/rubyonrails-core?hl=en.