lib/bindata/choice.rb in bindata-0.10.0 vs lib/bindata/choice.rb in bindata-0.11.0

- old
+ new

@@ -1,8 +1,6 @@ -require 'forwardable' require 'bindata/base' -require 'bindata/sanitize' require 'bindata/trace' module BinData # A Choice is a collection of data objects of which only one is active # at any particular time. Method calls will be delegated to the active @@ -53,27 +51,24 @@ # specifies the currently active choice. # <tt>:copy_on_change</tt>:: If set to true, copy the value of the previous # selection to the current selection whenever the # selection changes. Default is false. class Choice < BinData::Base - extend Forwardable register(self.name, self) mandatory_parameters :choices, :selection optional_parameter :copy_on_change class << self - def sanitize_parameters!(sanitizer, params) - if params.has_key?(:choices) + def sanitize_parameters!(params, sanitizer) + if params.needs_sanitizing?(:choices) choices = choices_as_hash(params[:choices]) ensure_valid_keys(choices) - params[:choices] = sanitized_choices(sanitizer, choices) + params[:choices] = sanitizer.create_sanitized_choices(choices) end - - super(sanitizer, params) end #------------- private @@ -95,25 +90,14 @@ def ensure_valid_keys(choices) if choices.has_key?(nil) raise ArgumentError, ":choices hash may not have nil key" end - if choices.keys.detect { |k| Symbol === k } + if choices.keys.detect { |key| Symbol === key } raise ArgumentError, ":choices hash may not have symbols for keys" end end - - def sanitized_choices(sanitizer, choices) - result = {} - choices.each_pair do |key, val| - type, param = val - the_class = sanitizer.lookup_class(type) - sanitized_params = sanitizer.sanitized_params(the_class, param) - result[key] = [the_class, sanitized_params] - end - result - end end def initialize(params = {}, parent = nil) super(params, parent) @@ -131,52 +115,54 @@ # This is deliberate to promote the declarative nature of BinData. # # If you really *must* be able to programmatically adjust the selection # then try something like the following. # - # class ProgrammaticChoice < BinData::Record - # choice :data, :choices => :choices, :selection => :selection - # attrib_accessor :selection + # class ProgrammaticChoice < BinData::Wrapper + # choice :selection => :selection + # attr_accessor :selection # end # # type1 = [:string, {:value => "Type1"}] # type2 = [:string, {:value => "Type2"}] # # choices = {5 => type1, 17 => type2} # pc = ProgrammaticChoice.new(:choices => choices) # # pc.selection = 5 - # pc.data #=> "Type1" + # pc #=> "Type1" # # pc.selection = 17 - # pc.data #=> "Type2" + # pc #=> "Type2" def selection=(v) raise NoMethodError end - def_delegators :current_choice, :clear, :clear? - - def respond_to?(symbol, include_private = false) - super || current_choice.respond_to?(symbol, include_private) + def clear + current_choice.clear end - def method_missing(symbol, *args, &block) - if current_choice.respond_to?(symbol) - current_choice.__send__(symbol, *args, &block) - else - super - end + def clear? + current_choice.clear? end def debug_name_of(child) debug_name end def offset_of(child) offset end + def respond_to?(symbol, include_private = false) + super || current_choice.respond_to?(symbol, include_private) + end + + def method_missing(symbol, *args, &block) + current_choice.__send__(symbol, *args, &block) + end + #--------------- private def _do_read(io) trace_selection @@ -200,12 +186,12 @@ def _do_write(io) current_choice.do_write(io) end - def _do_num_bytes(what) - current_choice.do_num_bytes(what) + def _do_num_bytes(deprecated) + current_choice.do_num_bytes(deprecated) end def _assign(val) current_choice.assign(val) end @@ -234,14 +220,14 @@ end obj end def instantiate_choice(selection) - choice_class, choice_params = get_parameter(:choices)[selection] - if choice_class.nil? + prototype = get_parameter(:choices)[selection] + if prototype.nil? raise IndexError, "selection '#{selection}' does not exist in :choices for #{debug_name}" end - choice_class.new(choice_params, self) + prototype.instantiate(self) end def copy_previous_value_if_required(selection, obj) prev = get_previous_choice(selection) if should_copy_value?(prev, obj)