Class: Roby::DelayedArgumentFromObject

Inherits:
Object
  • Object
show all
Extended by:
Roby::DRoby::V5::Builtins::ClassDumper
Includes:
Roby::DRoby::V5::DelayedArgumentFromObjectDumper
Defined in:
lib/roby/task_arguments.rb,
lib/roby/droby/enable.rb

Overview

Placeholder that can be used to assign an argument from an object's attribute, reading the attribute only when the task is started

This will usually not be used directly. One should use Task.from instead

Direct Known Subclasses

DelayedArgumentFromState

Instance Method Summary collapse

Methods included from Roby::DRoby::V5::Builtins::ClassDumper

droby_dump

Methods included from Roby::DRoby::V5::DelayedArgumentFromObjectDumper

#droby_dump

Constructor Details

#initialize(object, weak = true) ⇒ DelayedArgumentFromObject

Returns a new instance of DelayedArgumentFromObject.



570
571
572
573
574
575
# File 'lib/roby/task_arguments.rb', line 570

def initialize(object, weak = true)
    @object = object
    @methods = []
    @expected_class = Object
    @weak = weak
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(m, *args) ⇒ Object



676
677
678
679
680
681
682
# File 'lib/roby/task_arguments.rb', line 676

def method_missing(m, *args)
    if args.empty? && !block_given?
        dup.add_method(m)
    else
        super
    end
end

Instance Method Details

#==(other) ⇒ Object



684
685
686
687
688
# File 'lib/roby/task_arguments.rb', line 684

def ==(other)
    other.kind_of?(DelayedArgumentFromObject) &&
        @object.equal?(other.instance_variable_get(:@object)) &&
        @methods == other.instance_variable_get(:@methods)
end

#__expected_class__Class

The expected class of the resolved argument

The __ markers are used to avoid possible collisions with an actual method

Returns:



600
601
602
# File 'lib/roby/task_arguments.rb', line 600

def __expected_class__
    @expected_class
end

#__methods__Array<Symbol>

The chain of methods that are called on #__object__ to find the argument

The __ markers are used to avoid possible collisions with an actual method

Returns:

  • (Array<Symbol>)


591
592
593
# File 'lib/roby/task_arguments.rb', line 591

def __methods__
    @methods.dup
end

#__object__Object

The object from which the delayed argument is derived

The __ markers are used to avoid possible collisions with an actual method

Returns:



582
583
584
# File 'lib/roby/task_arguments.rb', line 582

def __object__
    @object
end

#add_method(m) ⇒ Object



617
618
619
620
# File 'lib/roby/task_arguments.rb', line 617

def add_method(m)
    @methods += [m]
    self
end

#can_merge?(task, other_task, other_arg) ⇒ Boolean

Returns:

  • (Boolean)


622
623
624
625
626
627
628
629
# File 'lib/roby/task_arguments.rb', line 622

def can_merge?(task, other_task, other_arg)
    catch(:no_value) do
        this_evaluated  = evaluate_delayed_argument(task)
        other_evaluated = other_arg.evaluate_delayed_argument(other_task)
        return other_evaluated == this_evaluated
    end
    false
end

#evaluate_delayed_argument(task) ⇒ Object



642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
# File 'lib/roby/task_arguments.rb', line 642

def evaluate_delayed_argument(task)
    result = @methods.inject(@object || task) do |v, m|
        if v.kind_of?(Roby::Task) && v.model.has_argument?(m)
            # We are trying to access a task argument, throw no_value if the
            # argument is not set
            unless v.arguments.key?(m)
                throw :no_value
            end

            argument = v.arguments.values[m]
            if TaskArguments.delayed_argument?(argument)
                argument.evaluate_delayed_argument(v)
            else
                argument
            end
        elsif v.respond_to?(m)
            begin v.send(m)
            rescue Exception
                throw :no_value
            end
        elsif @weak
            throw :no_value
        else
            task.failed_to_start!("#{v} has no method called #{m}")
            throw :no_value
        end
    end

    if @expected_class && !result.kind_of?(@expected_class)
        throw :no_value
    end
    result
end

#merge(task, other_task, other_arg) ⇒ Object



631
632
633
634
635
636
637
638
639
640
# File 'lib/roby/task_arguments.rb', line 631

def merge(task, other_task, other_arg)
    case other_arg
    when TaskArguments::StaticArgumentWrapper
        other_arg.value
    else
        # can_merge? return false if the value cannot be resolved
        # This is guaranteed to return a value
        evaluate_delayed_argument(task)
    end
end

#of_type(expected_class) ⇒ Object



604
605
606
# File 'lib/roby/task_arguments.rb', line 604

def of_type(expected_class)
    dup.of_type!(expected_class)
end

#of_type!(expected_class) ⇒ Object



608
609
610
611
# File 'lib/roby/task_arguments.rb', line 608

def of_type!(expected_class)
    @expected_class = expected_class
    self
end

#pretty_print(pp) ⇒ Object



694
695
696
# File 'lib/roby/task_arguments.rb', line 694

def pretty_print(pp)
    pp.text to_s
end

#strong?Boolean

Returns:

  • (Boolean)


613
614
615
# File 'lib/roby/task_arguments.rb', line 613

def strong?
    true
end

#to_sObject



690
691
692
# File 'lib/roby/task_arguments.rb', line 690

def to_s
    "delayed_argument_from(#{@object || 'task'}.#{@methods.map(&:to_s).join('.')})"
end