lib/bindata/multi_value.rb in bindata-0.9.1 vs lib/bindata/multi_value.rb in bindata-0.9.2

- old
+ new

@@ -14,37 +14,36 @@ # class SomeDataType < BinData::MultiValue # hide 'a' # # int32le :a # int16le :b - # tuple nil + # tuple :s # end # # obj = SomeDataType.new - # obj.field_names =># ["b", "x", "y", "z"] + # obj.field_names =># ["b", "s"] # # # == Parameters # # Parameters may be provided at initialisation to control the behaviour of # an object. These params are: # # <tt>:fields</tt>:: An array specifying the fields for this struct. # Each element of the array is of the form [type, name, # params]. Type is a symbol representing a registered - # type. Name is the name of this field. Name may be - # nil as in the example above. Params is an optional - # hash of parameters to pass to this field when - # instantiating it. + # type. Name is the name of this field. Params is an + # optional hash of parameters to pass to this field + # when instantiating it. # <tt>:hide</tt>:: A list of the names of fields that are to be hidden # from the outside world. Hidden fields don't appear # in #snapshot or #field_names but are still accessible # by name. # <tt>:endian</tt>:: Either :little or :big. This specifies the default # endian of any numerics in this struct, or in any # nested data objects. - class MultiValue < Struct + class MultiValue < BinData::Struct class << self # Register the names of all subclasses of this class. def inherited(subclass) #:nodoc: register(subclass.name, subclass) @@ -66,79 +65,73 @@ # Returns the names of any hidden fields in this struct. Any given args # are appended to the hidden list. def hide(*args) # note that fields are stored in an instance variable not a class var @hide ||= [] - args.each do |name| - next if name.nil? - @hide << name.to_s - end + @hide.concat(args.collect { |name| name.to_s }) @hide end - # Returns all stored fields. Should only be called by #sanitize_parameters + # Returns all stored fields. + # Should only be called by #sanitize_parameters def fields - @fields || [] + @fields ||= [] end # Used to define fields for this structure. def method_missing(symbol, *args) name, params = args type = symbol - name = (name.nil? or name == "") ? nil : name.to_s + name = name.to_s params ||= {} # note that fields are stored in an instance variable not a class var @fields ||= [] # check that type is known - if lookup(type, endian).nil? + unless Sanitizer.type_exists?(type, endian) raise TypeError, "unknown type '#{type}' for #{self}", caller end - # check that name is okay - if name != nil - # check for duplicate names - @fields.each do |t, n, p| - if n == name - raise SyntaxError, "duplicate field '#{name}' in #{self}", caller - end + # check for duplicate names + @fields.each do |t, n, p| + if n == name + raise SyntaxError, "duplicate field '#{name}' in #{self}", caller end + end - # check that name doesn't shadow an existing method - if self.instance_methods.include?(name) - raise NameError.new("", name), - "field '#{name}' shadows an existing method", caller - end + # check that name doesn't shadow an existing method + if self.instance_methods.include?(name) + raise NameError.new("", name), + "field '#{name}' shadows an existing method", caller + end - # check that name isn't reserved - if ::Hash.instance_methods.include?(name) - raise NameError.new("", name), - "field '#{name}' is a reserved name", caller - end + # check that name isn't reserved + if self::RESERVED.include?(name) + raise NameError.new("", name), + "field '#{name}' is a reserved name", caller end # remember this field. These fields will be recalled upon creating # an instance of this class @fields.push([type, name, params]) end # Returns a sanitized +params+ that is of the form expected # by #initialize. - def sanitize_parameters(params, endian = nil) + def sanitize_parameters(sanitizer, params) params = params.dup - # possibly override endian - endian = params[:endian] || self.endian || endian - unless endian.nil? - params[:endian] = endian - end + endian = params[:endian] || self.endian + fields = params[:fields] || self.fields + hide = params[:hide] || self.hide - params[:fields] = params[:fields] || self.fields - params[:hide] = params[:hide] || self.hide + params[:endian] = endian unless endian.nil? + params[:fields] = fields + params[:hide] = hide - super(params, endian) + super(sanitizer, params) end end end end