Class: MetaBuilder::ParameterType

Inherits:
Object
  • Object
show all
Defined in:
lib/MetaBuilder/parameter.rb,
lib/MetaBuilder/Qt4/parameter.rb

Overview

A class that handles a parameter type. It has to be subclassed to actually provide a parameter. The subclasses must provide the following:

  • a #string_to_type function to convert from string to the type;

  • a #type_to_string to convert back from type to string

  • an instance #type_name that returns a really small description of the type, to be used for instance to name command-line parameters.

  • a #type_name statement that registers the current class to the ParameterType system.

Moerover, it is a good idea to reimplement the #qt4_create_input_widget method; the default implementation works, but you probably wish it would look better.

Types are implemented using hashes: this way, additionnal parameters can easily be added. The hash must have a :type key that will be interpreted by the children of ParameterType. Examples:

{ :type => :integer}
{ :type => :file, :filter => "Text Files (*.txt)}

And so on. You definitely should document your type and it’s attributes properly, if you ever want that someone uses it.

The list of currently recognised types is here:

:integer

ParameterTypes::IntegerParameter

:float

ParameterTypes::FloatParameter

:string

ParameterTypes::StringParameter

:file

ParameterTypes::FileParameter

:boolean

ParameterTypes::BooleanParameter

:list

ParameterTypes::ListParameter

Additionally to the parameters the given type is requiring, you can pass some other kind of information using this hash, such as option parser short argument, aliases, and so on. This has nothing to do with type conversion, but it is the best place where to put this kind of things, in my humble opinion. The currently recognized such additional parameters are:

  • :option_parser_short: a short option name for option_parser.

  • :namespace: a ruby module that will be searched by #string_to_type for a constant. If one of the given name is found, its value is returned.

  • :shortctus: a hash specifiying strings shortcuts for given values.

Defined Under Namespace

Classes: IncorrectInput

Constant Summary collapse

@@parameter_types =

A hash that makes the :type value of the type argument correspond to a ParameterType child

{ }

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(type) ⇒ ParameterType

A default constructor. It should be safe to use it directly for children, unless something more specific is needed. Any descendent should always register type as @type - or, even better, call super.



81
82
83
84
85
86
# File 'lib/MetaBuilder/parameter.rb', line 81

def initialize(type)
  if type.is_a?(Symbol)
    type = {:type => type}
  end
  @type = type
end

Class Method Details

.from_string(type, string) ⇒ Object

Shortcut to convert directly a string to the given type specification. Handy shortcut.



124
125
126
# File 'lib/MetaBuilder/parameter.rb', line 124

def self.from_string(type, string)
  return get_type(type).string_to_type(string)
end

.get_param_type(type) ⇒ Object

This function converts a ‘description’ of the type wanted into a ParameterType child. Used by the Parameter system. As a special treat, a lone symbol is converted into

{:type => :symbol}


110
111
112
113
114
115
116
117
118
119
120
# File 'lib/MetaBuilder/parameter.rb', line 110

def self.get_param_type(type)
  if type.is_a?(Symbol)
    type = {:type => type}
  end
  raise "The type argument must be a Hash" unless type.is_a?(Hash)
  begin
    return @@parameter_types.fetch(type[:type])
  rescue
    raise "Type #{type[:type]} unknown to the parameter system"
  end
end

.get_type(type) ⇒ Object

Returns a ParameterType child instance suitable for conversion of the given type specification



130
131
132
# File 'lib/MetaBuilder/parameter.rb', line 130

def self.get_type(type)
  return get_param_type(type).new(type)
end

.type_name(name, public_name = nil, default_value = nil) ⇒ Object

This class function actually registers the current type to the ParameterType ancestor. name should be a symbol. Moreover, if the second argument is provided, it automatically creates a #type_name instance method returning this value.



92
93
94
95
96
97
98
99
100
101
102
103
104
# File 'lib/MetaBuilder/parameter.rb', line 92

def self.type_name(name, public_name = nil, default_value = nil)
  if @@parameter_types.has_key?(name)
    warn "Redefining type #{name} " +
      "from #{@@parameter_types[name]} to #{self}"
  end
  @@parameter_types[name] = self
  self.send(:define_method,:type_name) do
    public_name
  end
  self.send(:define_method,:default_value) do
    default_value
  end
end

Instance Method Details

#default_valueObject

Returns a default value for the given type. This is reimplemented systematically from children, with the ParameterType::type_name statement.



183
184
# File 'lib/MetaBuilder/parameter.rb', line 183

def default_value
end

#lookup_const(str) ⇒ Object

Looks for the value as a constant specified in the :namespace modules. Raises IncorrectInput if not found.

Raises:



188
189
190
191
192
193
194
195
196
197
# File 'lib/MetaBuilder/parameter.rb', line 188

def lookup_const(str)
  for mod in [@type[:namespace]].flatten
    begin
      return mod.const_get(str)
    rescue
      # Nothing, we still look up
    end
  end
  raise IncorrectInput, "Constant #{str} not found"
end

#option_parser_long_option(name) ⇒ Object

Returns a value to be fed to OptionParser#on as a ‘long’ option. It is separated from the rest to allow easy redefinition (in special cases). name is the name of the option.



238
239
240
# File 'lib/MetaBuilder/parameter.rb', line 238

def option_parser_long_option(name)
  return "--#{name} #{type_name.upcase}"
end

#option_parser_option(parser, name, desc, &block) ⇒ Object

Creates an option for the OptionParser parser. The block is fed with the converted value. The default implementation should be fine for most classes, but this still leaves the room for reimplementation if necessary. The parameters are:

  • parser: the OptionParser;

  • name: the name of the option;

  • desc: it description,

  • block: the block used to set the data.



227
228
229
230
231
232
233
# File 'lib/MetaBuilder/parameter.rb', line 227

def option_parser_option(parser, name, desc, &block)
  args = [option_parser_long_option(name), desc]
  if @type.has_key?(:option_parser_short)
    args.unshift(@type[:option_parser_short])
  end
  option_parser_raw(parser, *args, &block)
end

#option_parser_raw(parser, *args, &block) ⇒ Object

Creates on option for the OptionParser parser. The args will be fed directly to OptionParser#on. The block is called with the value in the target type.



210
211
212
213
214
215
216
# File 'lib/MetaBuilder/parameter.rb', line 210

def option_parser_raw(parser, *args, &block)
  b = block                 # For safe-keeping.
  c = proc do |str|
    b.call(string_to_type(str))
  end
  parser.on(*args, &c)
end

#qt4_create_input_widget(parent = nil, target = nil, style = nil) ⇒ Object

Creates a widget suitable for editing the value and returns it. The widget will be a child of parent (can be nil). The target is provided for the Parameter system. It should contain the value of the target whose parameter we should set. This can be used for instance when the value has dynamic content depending on some internals of target. Reimplementations should not fail if it is nil. The style parameter is for now a placeholder.

The created widget must provide the following:

  • text=|text: a writer|reader pair for the string value;

  • value=|value: a writer|reader pair for the real value;

  • value_changed() : a signal for when the value has changed. should be used in the same way as Qt::LineEdit::editingFinished in the sense that it should only trigger on complete output.

  • label=: a way to set the label. Label could be basically anything accepted by Qt; if it is nil or false, the display is switched off. The label display must be switched off by default.



48
49
50
# File 'lib/MetaBuilder/Qt4/parameter.rb', line 48

def qt4_create_input_widget(parent = nil, target = nil, style = nil)
  return Qt4MB::GenericInputWidget.new(parent, self)
end

#qt4_get(parent, title, label, default, target = nil) ⇒ Object

Pops up a Qt4 dialog box to ask for the value of the parameter.

  • parent is the parent widget;

  • title is the title of the Dialog Box

  • label is the label of the widget used for querying

  • default is the default value (of the appropriate type).

  • target is the target for the parameters system. Defaults to nil.

Returns directly a value in the right type. The default implementation uses the #qt4_create_input_widget function. As false or nil are appropriate return values in some cases, #qt4_get raises a CancelInput exception. You must handle it if you don’t want nasty surprises…



66
67
68
69
# File 'lib/MetaBuilder/Qt4/parameter.rb', line 66

def qt4_get(parent, title, label, default, target = nil)
  return Qt4MB::GenericDialog.get_type(parent, self,
                                       title, label, default, target)
end

#string_to_type(string) ⇒ Object

This function converts the given string to the appropriate type. It is a wrapper around the #string_to_type_internal function that can take advantage of a few general features. It is recommanded to define a #string_to_type_internal function rather to redefine #string_to_type



149
150
151
152
153
154
155
156
157
158
159
160
161
162
# File 'lib/MetaBuilder/parameter.rb', line 149

def string_to_type(string)
  # First, shortcuts:
  if @type.key?(:shortcuts) and @type[:shortcuts].key? string
    return stt_run_hook(@type[:shortcuts][string])
  end
  # Then, constants lookup.
  if @type.key?(:namespace)
    begin
      return stt_run_hook(lookup_const(string))
    rescue Exception
    end
  end
  return stt_run_hook(string_to_type_internal(string))
end

#stt_run_hook(val) ⇒ Object

Runs the string_to_type conversion hook



136
137
138
139
140
141
142
# File 'lib/MetaBuilder/parameter.rb', line 136

def stt_run_hook(val)
  if @type.key?(:stt_hook)
    return @type[:stt_hook].call(val)
  else
    val
  end
end

#type_nameObject

Returns a type name suitable for displaying, for instance, in an option parser, or inside a dialog box, and so on. Has to be one word (not to confuse the option parser, for instance); it is better if it is lowercase.



203
204
205
# File 'lib/MetaBuilder/parameter.rb', line 203

def type_name
  return 'notype'
end

#type_to_string(type) ⇒ Object

This function does the exact opposite of the #string_to_type one. It defaults to using the to_s methods of the parameter. Be careful: it is absolutely important that for any valid type,

string_to_type(type_to_string(type)) == type


169
170
171
# File 'lib/MetaBuilder/parameter.rb', line 169

def type_to_string(type)
  return type_to_string_internal(type)
end

#type_to_string_internal(type) ⇒ Object

The internal function for converting type to a string. Used by #type_to_string, children should only reimplement this function and leave #type_to_string



176
177
178
# File 'lib/MetaBuilder/parameter.rb', line 176

def type_to_string_internal(type)
  return type.to_s
end

#type_to_variant(value) ⇒ Object

Converts from the type to a QVariant



72
73
74
# File 'lib/MetaBuilder/Qt4/parameter.rb', line 72

def type_to_variant(value)
  return Qt::Variant.new(value)
end

#variant_to_type(variant) ⇒ Object

Converts from a QVariant to the appropriate (Ruby) type.



77
78
79
# File 'lib/MetaBuilder/Qt4/parameter.rb', line 77

def variant_to_type(variant)
  return variant.value
end