1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128
|
require 'bindata/lazy'
module BinData
module AcceptedParametersPlugin
# Mandatory parameters must be present when instantiating a data object.
def mandatory_parameters(*args)
accepted_parameters.mandatory(*args)
end
# Optional parameters may be present when instantiating a data object.
def optional_parameters(*args)
accepted_parameters.optional(*args)
end
# Default parameters can be overridden when instantiating a data object.
def default_parameters(*args)
accepted_parameters.default(*args)
end
# Mutually exclusive parameters may not all be present when
# instantiating a data object.
def mutually_exclusive_parameters(*args)
accepted_parameters.mutually_exclusive(*args)
end
alias mandatory_parameter mandatory_parameters
alias optional_parameter optional_parameters
alias default_parameter default_parameters
def accepted_parameters #:nodoc:
@accepted_parameters ||= begin
ancestor_params = superclass.respond_to?(:accepted_parameters) ?
superclass.accepted_parameters : nil
AcceptedParameters.new(ancestor_params)
end
end
# BinData objects accept parameters when initializing. AcceptedParameters
# allow a BinData class to declaratively identify accepted parameters as
# mandatory, optional, default or mutually exclusive.
class AcceptedParameters
def initialize(ancestor_parameters = nil)
if ancestor_parameters
@mandatory = ancestor_parameters.mandatory.dup
@optional = ancestor_parameters.optional.dup
@default = ancestor_parameters.default.dup
@mutually_exclusive = ancestor_parameters.mutually_exclusive.dup
else
@mandatory = []
@optional = []
@default = Hash.new
@mutually_exclusive = []
end
end
def mandatory(*args)
unless args.empty?
@mandatory.concat(to_syms(args))
@mandatory.uniq!
end
@mandatory
end
def optional(*args)
unless args.empty?
@optional.concat(to_syms(args))
@optional.uniq!
end
@optional
end
def default(args = nil)
if args
to_syms(args.keys) # call for side effect of validating names
args.each_pair do |param, value|
@default[param.to_sym] = value
end
end
@default
end
def mutually_exclusive(*args)
arg1 = args.shift
until args.empty?
args.each do |arg2|
@mutually_exclusive.push([arg1.to_sym, arg2.to_sym])
@mutually_exclusive.uniq!
end
arg1 = args.shift
end
@mutually_exclusive
end
def all
(@mandatory + @optional + @default.keys).uniq
end
#---------------
private
def to_syms(args)
syms = args.collect(&:to_sym)
ensure_valid_names(syms)
syms
end
def ensure_valid_names(names)
invalid_names = self.class.invalid_parameter_names
names.each do |name|
if invalid_names.include?(name)
raise NameError.new("Rename parameter '#{name}' " \
"as it shadows an existing method.", name)
end
end
end
def self.invalid_parameter_names
@invalid_names ||= begin
all_names = LazyEvaluator.instance_methods(true)
allowed_names = [:name, :type]
invalid_names = (all_names - allowed_names).uniq
Hash[*invalid_names.collect { |key| [key.to_sym, true] }.flatten]
end
end
end
end
end
|