class Roby::TaskArguments
Class
that handles task arguments. They are handled specially as the arguments cannot be overwritten and can not be changed by a task that is not owned.
Attributes
Public Class Methods
# File lib/roby/task_arguments.rb, line 16 def self.delayed_argument?(obj) obj.respond_to?(:evaluate_delayed_argument) end
# File lib/roby/task_arguments.rb, line 9 def initialize(task) @task = task @static = true @values = Hash.new super() end
Public Instance Methods
True if the arguments are equal
Both proper values and delayed values have to be equal
@return [Boolean]
# File lib/roby/task_arguments.rb, line 94 def ==(hash) to_hash == hash.to_hash end
# File lib/roby/task_arguments.rb, line 195 def [](key) key = warn_deprecated_non_symbol_key(key) value = values[key] if !TaskArguments.delayed_argument?(value) value end end
Assigns a value to a given argument name
The method validates that writing this argument value is allowed
@raise OwnershipError
if we don't own the task @raise ArgumentError if the argument is already set
# File lib/roby/task_arguments.rb, line 168 def []=(key, value) key = warn_deprecated_non_symbol_key(key) if writable?(key, value) if !value.droby_marshallable? raise NotMarshallable, "values used as task arguments must be marshallable, attempting to set #{key} to #{value} of class #{value.class}, which is not" elsif !task.read_write? raise OwnershipError, "cannot change the argument set of a task which is not owned #{task} is owned by #{task.owners} and #{task.plan} by #{task.plan.owners}" end if TaskArguments.delayed_argument?(value) @static = false elsif values.has_key?(key) && TaskArguments.delayed_argument?(values[key]) update_static = true end values[key] = value task.plan.log(:task_arguments_updated, task, key, value) if update_static @static = values.all? { |k, v| !TaskArguments.delayed_argument?(v) } end value else raise ArgumentError, "cannot override task argument #{key} as it is already set to #{values[key]}" end end
Tests if a given argument has been assigned, that is either has a static value or has a delayed value object
# File lib/roby/task_arguments.rb, line 79 def assigned?(key) has_key?(key) end
Returns the set of arguments for which a proper value has been assigned
@return [Hash]
# File lib/roby/task_arguments.rb, line 115 def assigned_arguments result = Hash.new each_assigned_argument do |k, v| result[k] = v end result end
# File lib/roby/task_arguments.rb, line 72 def dup; self.to_hash end
# File lib/roby/task_arguments.rb, line 133 def each(&block) values.each(&block) end
Enumerates the arguments that have been explicitly assigned
# File lib/roby/task_arguments.rb, line 124 def each_assigned_argument return assigned_arguments if !block_given? each do |key, value| if !TaskArguments.delayed_argument?(value) yield(key, value) end end end
Returns this argument set, but with the delayed arguments evaluated
@return [Hash]
# File lib/roby/task_arguments.rb, line 206 def evaluate_delayed_arguments result = Hash.new values.each do |key, val| if TaskArguments.delayed_argument?(val) catch(:no_value) do result[key] = val.evaluate_delayed_argument(task) end else result[key] = val end end result end
# File lib/roby/task_arguments.rb, line 220 def force_merge!(hash) if task.plan && task.plan.executable? values.merge!(hash) do |k, _, v| task.plan.log(:task_arguments_updated, task, k, v) v end else values.merge!(hash) end @static = values.all? { |k, v| !TaskArguments.delayed_argument?(v) } end
True if an argument with that name is assigned, be it a proper value or a delayed value object
# File lib/roby/task_arguments.rb, line 40 def has_key?(key) values.has_key?(key) end
The set of argument names that have been assigned so far, either with a proper object or a delayed value object
# File lib/roby/task_arguments.rb, line 46 def keys values.keys end
# File lib/roby/task_arguments.rb, line 232 def merge!(**hash) hash.each do |key, value| if !value.droby_marshallable? raise NotMarshallable, "values used as task arguments must be marshallable, attempting to set #{key} to #{value}, which is not" end end values.merge!(hash) do |key, old, new| if old == new then old elsif writable?(key, new) task.plan.log(:task_arguments_updated, task, key, new) new else raise ArgumentError, "cannot override task argument #{key}: trying to replace #{old} by #{new}" end end @static = values.all? { |k, v| !TaskArguments.delayed_argument?(v) } self end
Pretty-prints this argument set
# File lib/roby/task_arguments.rb, line 99 def pretty_print(pp) pp.seplist(values) do |keyvalue| key, value = *keyvalue pp.text "#{key}: " value.pretty_print(pp) end end
Return the value stored for the given key as-is
# File lib/roby/task_arguments.rb, line 34 def raw_get(key) values[key] end
Tests if a given argument has been set with a proper value (not a delayed value object)
# File lib/roby/task_arguments.rb, line 85 def set?(key) has_key?(key) && !TaskArguments.delayed_argument?(values.fetch(key)) end
Returns the listed set of arguments
@param [Array<Symbol>] args the argument names
Delayed arguments are evaluated before it is sliced
# File lib/roby/task_arguments.rb, line 68 def slice(*args) evaluate_delayed_arguments.slice(*args) end
True if none of the argument values are delayed objects
# File lib/roby/task_arguments.rb, line 21 def static? @static end
# File lib/roby/task_arguments.rb, line 73 def to_hash values.dup end
# File lib/roby/task_arguments.rb, line 107 def to_s values.sort_by(&:first).map { |k, v| "#{k}: #{v}" }.join(", ") end
Updates the given argument, regardless of whether it is allowed or not
@see {#writable?} @param [Symbol] key the argument name @param [Object] value the new argument value @return [Object]
# File lib/roby/task_arguments.rb, line 143 def update!(key, value) if values.has_key?(key) current_value = values[key] is_updated = (current_value != value) update_static = TaskArguments.delayed_argument?(current_value) else is_updated = true end values[key] = value if is_updated task.plan.log(:task_arguments_updated, task, key, value) end if TaskArguments.delayed_argument?(value) @static = false elsif update_static @static = values.all? { |k, v| !TaskArguments.delayed_argument?(v) } end end
# File lib/roby/task_arguments.rb, line 25 def warn_deprecated_non_symbol_key(key) if !key.kind_of?(Symbol) Roby.warn_deprecated "accessing arguments using anything else than a symbol is deprecated", 2 key.to_sym else key end end
True if it is possible to write the given value to the given argument
@param [Symbol] key the argument name @param [Object] value the new argument value
# File lib/roby/task_arguments.rb, line 54 def writable?(key, value) if has_key?(key) !task.model.arguments.include?(key) || TaskArguments.delayed_argument?(values[key]) else true end end