Class: BinData::Choice

Inherits:
Base
  • Object
show all
Defined in:
lib/bindata/choice.rb

Overview

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 choice.

require 'bindata'

type1 = [:string, {:value => "Type1"}]
type2 = [:string, {:value => "Type2"}]

choices = {5 => type1, 17 => type2}
a = BinData::Choice.new(:choices => choices, :selection => 5)
a.value # => "Type1"

choices = [ type1, type2 ]
a = BinData::Choice.new(:choices => choices, :selection => 1)
a.value # => "Type2"

choices = [ nil, nil, nil, type1, nil, type2 ]
a = BinData::Choice.new(:choices => choices, :selection => 3)
a.value # => "Type1"

mychoice = 'big'
choices = {'big' => :uint16be, 'little' => :uint16le}
a = BinData::Choice.new(:choices => choices,
                        :selection => lambda { mychoice })
a.value  = 256
a.to_binary_s #=> "\001\000"
mychoice.replace 'little'
a.selection #=> 'little'
a.to_binary_s #=> "\000\001"

Parameters

Parameters may be provided at initialisation to control the behaviour of an object. These params are:

:choices

Either an array or a hash specifying the possible data objects. The format of the array/hash.values is a list of symbols representing the data object type. If a choice is to have params passed to it, then it should be provided as [type_symbol, hash_params]. An implementation constraint is that the hash may not contain symbols as keys.

:selection

An index/key into the :choices array/hash which specifies the currently active choice.

:copy_on_change

If set to true, copy the value of the previous selection to the current selection whenever the selection changes. Default is false.

Instance Attribute Summary

Attributes inherited from Base

#parent

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from Base

#==, #assign, #debug_name, #debug_name_of, #eval_parameter, #get_parameter, #has_parameter?, #inspect, #num_bytes, #offset, #offset_of, #pretty_print, #read, read, register, register_class, register_self, register_subclasses, #rel_offset, #snapshot, #to_binary_s, #to_s, #write

Methods included from AcceptedParametersMixin

included

Constructor Details

#initialize(parameters = {}, parent = nil) ⇒ Choice

Returns a new instance of Choice.



101
102
103
104
105
106
# File 'lib/bindata/choice.rb', line 101

def initialize(parameters = {}, parent = nil)
  super

  @choices = {}
  @last_selection = nil
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(symbol, *args, &block) ⇒ Object

:nodoc:



152
153
154
# File 'lib/bindata/choice.rb', line 152

def method_missing(symbol, *args, &block) #:nodoc:
  current_choice.__send__(symbol, *args, &block)
end

Class Method Details

.sanitize_parameters!(params, sanitizer) ⇒ Object

:nodoc:



64
65
66
67
68
69
70
# File 'lib/bindata/choice.rb', line 64

def sanitize_parameters!(params, sanitizer) #:nodoc:
  if params.needs_sanitizing?(:choices)
    choices = choices_as_hash(params[:choices])
    ensure_valid_keys(choices)
    params[:choices] = sanitizer.create_sanitized_choices(choices)
  end
end

Instance Method Details

#clearObject

:nodoc:



140
141
142
# File 'lib/bindata/choice.rb', line 140

def clear #:nodoc:
  current_choice.clear
end

#clear?Boolean

:nodoc:

Returns:

  • (Boolean)


144
145
146
# File 'lib/bindata/choice.rb', line 144

def clear? #:nodoc:
  current_choice.clear?
end

#respond_to?(symbol, include_private = false) ⇒ Boolean

:nodoc:

Returns:

  • (Boolean)


148
149
150
# File 'lib/bindata/choice.rb', line 148

def respond_to?(symbol, include_private = false) #:nodoc:
  current_choice.respond_to?(symbol, include_private) || super
end

#selectionObject

A convenience method that returns the current selection.



109
110
111
# File 'lib/bindata/choice.rb', line 109

def selection
  eval_parameter(:selection)
end

#selection=(sel) ⇒ Object

This method does not exist. This stub only exists to document why. There is no #selection= method to complement the #selection method. 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::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 #=> "Type1"

pc.selection = 17
pc #=> "Type2"

Raises:

  • (NoMethodError)


136
137
138
# File 'lib/bindata/choice.rb', line 136

def selection=(sel)
  raise NoMethodError, "See rdoc BinData::Choice.selection= for details"
end