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.



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

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



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

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

Instance Method Details

#==(other) ⇒ Object



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

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:



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

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>)


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

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:



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

def __object__
    @object
end

#add_method(m) ⇒ Object



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

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

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

Returns:

  • (Boolean)


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

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



641
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
# File 'lib/roby/task_arguments.rb', line 641

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



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

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



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

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

#of_type!(expected_class) ⇒ Object



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

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

#pretty_print(pp) ⇒ Object



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

def pretty_print(pp)
    pp.text to_s
end

#strong?Boolean

Returns:

  • (Boolean)


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

def strong?
    true
end

#to_sObject



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

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