method_missing
and
respond_to_missing?
in sync.
(A brief refresher: in 2011, Avdi Grimm wrote a blog post about that. In the comments, I wrote up a quick and dirty hack to do so, in very restricted cases, and then a still-dirty improvement, that unfortunately has since been mangled somehow.)
At RubyConf 2014, Betsy Haibel spoke on Ruby metaprogramming, including that same need. That inspired me to work on the concept again, taking a different approach (essentially a decorator) that I had briefly considered in those comments.
The result is my new gem HookLyingSyncer. (I was going to call it FirstResponder, but that name was already taken.) The code is at https://github.com/davearonson/hook_lying_syncer. For now, the code looks like:
class HookLyingSyncer
def initialize(object, matcher, &block)
@object = object
@matcher = matcher
@block = block
end
private
def respond_to_missing?(sym, include_all=false)
matches = find_matches(sym)
matches.any? ? true : @object.send(:respond_to?, sym, include_all)
end
def method_missing(sym, *args, &blk)
matches = find_matches(sym)
if matches.any?
@block.call(@object, matches, *args)
else
@object.send(sym, *args, &blk)
end
end
def find_matches(sym)
result = @matcher.call(sym)
result ? result : []
end
end
The tests contain some examples, with further usage explanation
in the README. Long story short, it can be used on
instances and classes, to add or override method definitions,
including overriding new
so as to add methods to all new instances
of a class.
This is my first time actually making a gem, and I haven't done much with metaprogramming before, especially something that other people are going to use to do their metaprogramming. So, any feedback would be greatly appreciated!
No comments:
Post a Comment
Note: Only a member of this blog may post a comment.