Class: CTioga2::Data::Backends::Backend
- Inherits:
-
Object
- Object
- CTioga2::Data::Backends::Backend
- Extended by:
- BackendDescriptionExtend
- Includes:
- Log
- Defined in:
- lib/ctioga2/data/backends/backend.rb
Overview
This class provides the infrastructure for accessing data sets. It shouldn’t be used directly, but rather subclassed and reimplemented. The aim of this class is to provide any software which is interested to retrive data from some source with a consistent way to do so, independent the kind of source accessed.
todo update documentation.
Subclasses should:
-
provide a consistent method for creating themselves, with as much information as necessary, including options and default parameters. Actually, their initialize function should take no value but on the other side, the BackendDescription associated with it should make it easy to set all the parameters necessary to get one set of data.
-
provide a way to fill an OptionParser with their own parameters
-
provide a way to retrieve the data via named ‘sets’ (either 2D or 3D data, depending on the subclass)
-
provide a way to obtain all meta-informations on one dataset, such as the date, the meaning of the columns (if any), and so on.
-
provide a way to know which named sets are available, or at least a subset (or nothing if we don’t know a thing).
-
wether the actual reading of the data is done at initialization time or at query time is left to the implementor ;-) !
todo adapt to the new structure.
todo add back filters (with time)
todo add a Cache ?
Direct Known Subclasses
DirectBackend, GnuplotBackend, MathBackend, SMathBackend, TextBackend
Class Method Summary collapse
-
.describe(name, longname, desc, register = true) ⇒ Object
Creates a description object with the given texts and associates it with the class.
-
.list_backends ⇒ Object
Returns a hash containing the description of all available backends.
Instance Method Summary collapse
-
#dataset(set) ⇒ Object
Public interface to query DataSet from a Backend.
-
#description ⇒ Object
Returns the BackendDescription associated with this Backend.
-
#expand_sets(spec) ⇒ Object
When converting a user input into a set, a program should always use this function, unless it has really good reasons for that.
-
#has_set?(set) ⇒ Boolean
(also: #set?)
Returns true if the backend can provide data for the given set.
-
#initialize ⇒ Backend
constructor
Sets up a few things, such as the filters.
-
#set_param_from_string(param, string) ⇒ Object
Directly set a named parameter.
-
#sets_available ⇒ Object
Some backends have a pretty good idea of the sets available for use.
Methods included from BackendDescriptionExtend
base_description, create_factory, describe, factory_class, factory_description, factory_description_hash, factory_description_list, has_factory?, inherit_parameters, param, param_accessor, param_reader, param_writer, register_class, set_description
Methods included from Log
context, counts, debug, error, fatal, #format_exception, #identify, info, init_logger, log_to, logger, set_level, #spawn, warn
Constructor Details
#initialize ⇒ Backend
Sets up a few things, such as the filters.
73 74 |
# File 'lib/ctioga2/data/backends/backend.rb', line 73 def initialize end |
Class Method Details
.describe(name, longname, desc, register = true) ⇒ Object
Creates a description object with the given texts and associates it with the class. It is necessary to have this statement before any parameter declaration. If you don’t set any description, you will not be able to benefit from the plugin system. To be used in Backend subclasses, simply this way:
describe "biniou", "Biniou backend", "A backend to deal with Binious"
90 91 92 93 |
# File 'lib/ctioga2/data/backends/backend.rb', line 90 def Backend.describe(name, longname, desc, register = true) d = BackendDescription.new(self, name, longname, desc, register) set_description(d) end |
.list_backends ⇒ Object
Returns a hash containing the description of all available backends
97 98 99 |
# File 'lib/ctioga2/data/backends/backend.rb', line 97 def Backend.list_backends return factory_description_hash end |
Instance Method Details
#dataset(set) ⇒ Object
Public interface to query DataSet from a Backend. Children must redefine #query_dataset rather than this function. This function also applies filters and does othe kinds of transformations
129 130 131 |
# File 'lib/ctioga2/data/backends/backend.rb', line 129 def dataset(set) return query_dataset(set) end |
#description ⇒ Object
Returns the BackendDescription associated with this Backend.
77 78 79 |
# File 'lib/ctioga2/data/backends/backend.rb', line 77 def description return self.class.description end |
#expand_sets(spec) ⇒ Object
When converting a user input into a set, a program should always use this function, unless it has really good reasons for that.
The default implementation is to expand 2##4 to 2, 3, 4. Can be useful even for mathematical stuff.
Another thing is recognised and expanded: #<2<i*2>,5> runs the code i*2 with the values from 2 to 5 and returns the result. The code in the middle is a Ruby block, and therefore should be valid !
A third expansion is now available: #<a = 2<a * sin(x)>10> will expand into 2*sin(x) , 3*sin(x) … 10*sin(x) it is different than the previous in the sense that the code in the middle is not a Ruby code, but a mere string, which means there won’t be compilation problems.
Unless your backend can’t accomodate for that, all redefinitions of this function should check for their specific signatures first and call this function if they fail. This way, they will profit from improvements in this code while keeping old stuff working.
157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 |
# File 'lib/ctioga2/data/backends/backend.rb', line 157 def (spec) if m = /(\d+)##(\d+)/.match(spec) debug { "Using expansion rule #1" } a = m[1].to_i b = m[2].to_i ret = [] a.upto(b) do |i| ret << m.pre_match + i.to_s + m.post_match end return ret elsif m = /\#<(\d+)<(.*?)>(\d+)>/.match(spec) debug { "Using expansion rule #2" } from = m[1].to_i to = m[3].to_i debug { "Ruby code used for expansion: {|i| #{m[2]} }" } code = eval "proc {|i| #{m[2]} }" ret = [] from.upto(to) do |i| ret << m.pre_match + code.call(i).to_s + m.post_match end return ret elsif m = /\#<\s*(\w+)\s*=\s*(\d+)\s*<(.*?)>\s*(\d+)\s*>/.match(spec) debug { "Using expansion rule #3" } var = m[1] from = m[2].to_i to = m[4].to_i # Then we replace all occurences of the variable literal = '"' + m[3].gsub(/\b#{var}\b/, '#{' + var + '}') + '"' debug { "Ruby code used for expansion: {|#{var}| #{literal} }" } code = eval "proc {|#{var}| #{literal} }" ret = [] from.upto(to) do |i| ret << m.pre_match + code.call(i).to_s + m.post_match end return ret end # Fallback return [spec] rescue Exception => ex # In case something went wrong in the eval. warn { "An error occured during expansion of '#{spec}': #{ex.}" } debug { "Error backtrace: #{ex.backtrace.join "\n"}" } warn { "Ignoring, but you're nearly garanteed something will "+ "fail later on" } return [spec] end |
#has_set?(set) ⇒ Boolean Also known as: set?
Returns true if the backend can provide data for the given set.
118 119 120 |
# File 'lib/ctioga2/data/backends/backend.rb', line 118 def has_set?(set) return false end |
#set_param_from_string(param, string) ⇒ Object
Directly set a named parameter
220 221 222 |
# File 'lib/ctioga2/data/backends/backend.rb', line 220 def set_param_from_string(param, string) description.param_hash[param].set_from_string(self, string) end |
#sets_available ⇒ Object
Some backends have a pretty good idea of the sets available for use. Some really don’t. You can choose to reimplement this function if you can provide a useful list of sets for your backend. This list doesn’t need to be exhaustive (and is most unlikely to be). It can also return something that would need further expansion using expand_sets.
212 213 214 |
# File 'lib/ctioga2/data/backends/backend.rb', line 212 def sets_available return [] end |