lib/bond/missions/object_mission.rb in bond-0.1.4 vs lib/bond/missions/object_mission.rb in bond-0.2.0

- old
+ new

@@ -1,49 +1,46 @@ -# Represents a completion mission specified by :object in Bond.complete. Unlike other missions, this -# one needs to both match the mission condition and have the current object being completed have -# an ancestor specified by :object. -class Bond::Missions::ObjectMission < Bond::Mission +# A mission which completes an object's methods. For this mission to match, +# the condition must match and the current object must have an ancestor that matches :object. +# Note: To access to the current object being completed on within an action, use the input's +# object attribute. +# +# ==== Bond.complete Options: +# [*:object*] String representing a module/class of object whose methods are completed. +# [*:action*] If an action is not specified, the default action is to complete an object's +# non-operator methods. +# +# ===== Example: +# Bond.complete(:object=>ActiveRecord::Base) {|input| input.object.class.instance_methods(false) } +class Bond::ObjectMission < Bond::Mission #:stopdoc: - attr_reader :object_condition - + OBJECTS = %w<\S+> + Bond::Mission::OBJECTS + CONDITION = '(OBJECTS)\.(\w*(?:\?|!)?)$' def initialize(options={}) - @object_condition = options.delete(:object) - @object_condition = /^#{Regexp.escape(@object_condition.to_s)}$/ unless @object_condition.is_a?(Regexp) - options[:on] ||= /(\S+|[^.]+)\.([^.\s]*)$/ - @eval_binding = options[:eval_binding] + @object_condition = /^#{options[:object]}$/ + options[:on] ||= Regexp.new condition_with_objects super end def unique_id - "#{@object_condition.inspect}+#{@condition.inspect}" + "#{@object_condition.inspect}+#{@on.inspect}" end - def handle_valid_match(input) - if (match = super) - begin - eval_object(match) - rescue Exception - return false - end - if (match = @evaled_object.class.ancestors.any? {|e| e.to_s =~ @object_condition }) - @completion_prefix = @matched[1] + "." - @input = @matched[2] - @input.instance_variable_set("@object", @evaled_object) - @input.instance_eval("def self.object; @object ; end") - @action ||= lambda {|e| default_action(e.object) } - else - match = false - end - end - match + def do_match(input) + super && eval_object(@matched[1]) && @evaled_object.class.respond_to?(:ancestors) && + @evaled_object.class.ancestors.any? {|e| e.to_s =~ @object_condition } end - def eval_object(match) - @matched = match - @evaled_object = self.class.current_eval(match[1], @eval_binding) + def after_match(input) + @completion_prefix = @matched[1] + "." + @action ||= lambda {|e| default_action(e.object) } + create_input @matched[2], :object=>@evaled_object end def default_action(obj) obj.methods.map {|e| e.to_s} - OPERATORS + end + + def match_message + "Matches completion for object with ancestor matching #{@object_condition.inspect}." end #:startdoc: end \ No newline at end of file