ctioga2 0.6.1 → 0.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/Changelog +12 -0
- data/lib/ctioga2/commands/commands.rb +2 -1
- data/lib/ctioga2/commands/doc/help.rb +17 -7
- data/lib/ctioga2/commands/general-types.rb +8 -1
- data/lib/ctioga2/commands/interpreter.rb +3 -2
- data/lib/ctioga2/data/backends/backends/text.rb +13 -3
- data/lib/ctioga2/data/stack.rb +17 -2
- data/lib/ctioga2/graphics/elements/containers.rb +2 -1
- data/lib/ctioga2/graphics/elements/curve2d.rb +13 -19
- data/lib/ctioga2/graphics/elements/element.rb +51 -16
- data/lib/ctioga2/graphics/elements/parametric2d.rb +25 -31
- data/lib/ctioga2/graphics/elements/primitive.rb +20 -2
- data/lib/ctioga2/graphics/elements/subplot.rb +47 -9
- data/lib/ctioga2/graphics/elements/xyz-contour.rb +1 -10
- data/lib/ctioga2/graphics/elements/xyz-map.rb +2 -19
- data/lib/ctioga2/graphics/generator.rb +21 -4
- data/lib/ctioga2/graphics/styles/box.rb +63 -2
- data/lib/ctioga2/graphics/styles/colormap.rb +2 -2
- data/lib/ctioga2/graphics/styles/curve.rb +17 -1
- data/lib/ctioga2/graphics/styles/factory.rb +9 -2
- data/lib/ctioga2/graphics/styles/plot-types.rb +123 -0
- data/lib/ctioga2/graphics/styles/plot.rb +22 -4
- data/lib/ctioga2/graphics/types.rb +4 -2
- data/lib/ctioga2/log.rb +5 -2
- data/lib/ctioga2/metabuilder/type.rb +33 -9
- data/lib/ctioga2/plotmaker.rb +8 -2
- data/lib/ctioga2/postprocess.rb +39 -8
- data/lib/ctioga2/utils.rb +93 -3
- metadata +3 -2
@@ -0,0 +1,123 @@
|
|
1
|
+
# contour.rb: the style of a contour plot
|
2
|
+
# copyright (c) 2009 by Vincent Fourmond
|
3
|
+
|
4
|
+
# This program is free software; you can redistribute it and/or modify
|
5
|
+
# it under the terms of the GNU General Public License as published by
|
6
|
+
# the Free Software Foundation; either version 2 of the License, or
|
7
|
+
# (at your option) any later version.
|
8
|
+
|
9
|
+
# This program is distributed in the hope that it will be useful,
|
10
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
11
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
12
|
+
# GNU General Public License for more details (in the COPYING file).
|
13
|
+
|
14
|
+
require 'ctioga2/utils'
|
15
|
+
require 'ctioga2/log'
|
16
|
+
|
17
|
+
|
18
|
+
# This module contains all the classes used by ctioga
|
19
|
+
module CTioga2
|
20
|
+
|
21
|
+
Version::register_svn_info('$Revision$', '$Date$')
|
22
|
+
|
23
|
+
module Graphics
|
24
|
+
|
25
|
+
module Styles
|
26
|
+
|
27
|
+
StyleAspectRE = {
|
28
|
+
/^marker[_-]color$/i => :marker_color,
|
29
|
+
/^marker[_-](size|scale)$/i => :marker_scale,
|
30
|
+
}
|
31
|
+
|
32
|
+
StyleAspect =
|
33
|
+
CmdType.new('style-aspect', {:type => :re_list,
|
34
|
+
:list => StyleAspectRE}, <<EOD)
|
35
|
+
|
36
|
+
This type designs which aspect of the style of a
|
37
|
+
{command: xy-parametric} plot is controlled by a certain Z value.
|
38
|
+
It can take the following values:
|
39
|
+
* @marker_color@: the color for the markers
|
40
|
+
* @marker_size@/@marker_scale@: the size of the markers
|
41
|
+
EOD
|
42
|
+
|
43
|
+
# This class defines how the Z values are converted into
|
44
|
+
# stylistic information
|
45
|
+
class ParametricPlotStyle < BasicStyle
|
46
|
+
|
47
|
+
# What is the z1 axis
|
48
|
+
typed_attribute :z1, 'style-aspect'
|
49
|
+
|
50
|
+
# What is the z2 axis
|
51
|
+
typed_attribute :z2, 'style-aspect'
|
52
|
+
|
53
|
+
def initialize
|
54
|
+
@z1 = :marker_color
|
55
|
+
end
|
56
|
+
|
57
|
+
def prepare
|
58
|
+
@reversed = {}
|
59
|
+
|
60
|
+
2.times do |i|
|
61
|
+
val = self.send("z#{i+1}")
|
62
|
+
if val
|
63
|
+
@reversed[val] = i
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
# Returns the marker style for the given Z values.
|
69
|
+
#
|
70
|
+
# This will only work if #prepare has been called first !
|
71
|
+
def marker_style(curve_style, zvalue, zmin, zmax)
|
72
|
+
|
73
|
+
style = curve_style.marker.dup
|
74
|
+
|
75
|
+
if @reversed[:marker_scale]
|
76
|
+
idx = @reversed[:marker_scale]
|
77
|
+
if idx < zvalue.size
|
78
|
+
max_scale = curve_style.marker.scale || 1.0
|
79
|
+
|
80
|
+
## @todo Later on, when a min_marker_scale is provided,
|
81
|
+
## then the scale will be constrained between the min
|
82
|
+
## and max. For now, it is simply proportionnal to the
|
83
|
+
## absolute value of the largest.
|
84
|
+
min_scale = curve_style.marker_min_scale
|
85
|
+
|
86
|
+
zm = zmin[idx]
|
87
|
+
zM = zmax[idx]
|
88
|
+
|
89
|
+
mm = zM.abs
|
90
|
+
m2 = zm.abs
|
91
|
+
mm = m2 if m2 > mm
|
92
|
+
|
93
|
+
z = zvalue[idx]
|
94
|
+
|
95
|
+
style.scale = if min_scale
|
96
|
+
min_scale + (max_scale - min_scale) *
|
97
|
+
(z - zm)/(zM - zm)
|
98
|
+
else
|
99
|
+
zvalue[idx].abs/mm * max_scale
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
end
|
104
|
+
|
105
|
+
if @reversed[:marker_color]
|
106
|
+
idx = @reversed[:marker_color]
|
107
|
+
if idx < zvalue.size
|
108
|
+
style.color = curve_style.marker_color_map.z_color(zvalue[idx],
|
109
|
+
zmin[idx],
|
110
|
+
zmax[idx])
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
return style
|
115
|
+
|
116
|
+
end
|
117
|
+
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
@@ -19,7 +19,7 @@ require 'ctioga2/graphics/coordinates'
|
|
19
19
|
# This module contains all the classes used by ctioga
|
20
20
|
module CTioga2
|
21
21
|
|
22
|
-
Version::register_svn_info('$Revision:
|
22
|
+
Version::register_svn_info('$Revision: 521 $', '$Date: 2013-09-21 18:55:05 +0200 (Sat, 21 Sep 2013) $')
|
23
23
|
|
24
24
|
module Graphics
|
25
25
|
|
@@ -355,13 +355,27 @@ EOH
|
|
355
355
|
|
356
356
|
end
|
357
357
|
|
358
|
+
asco = AxisStyleOptions.dup
|
359
|
+
asco['also-axes'] = CmdArg.new('axis')
|
360
|
+
|
358
361
|
AxisStyleCommand =
|
359
362
|
Cmd.new("axis-style",nil,"--axis-style",
|
360
363
|
[
|
361
364
|
CmdArg.new('axis'),
|
362
|
-
],
|
363
|
-
|
364
|
-
|
365
|
+
], asco) do |plotmaker, which, opts|
|
366
|
+
axes = [which]
|
367
|
+
if opts['also-axes']
|
368
|
+
axes += opts['also-axes'].split(/\s*,\s*/)
|
369
|
+
end
|
370
|
+
|
371
|
+
for w in axes
|
372
|
+
begin
|
373
|
+
style = AxisStyle.current_axis_style(plotmaker, w)
|
374
|
+
style.set_from_hash(opts)
|
375
|
+
rescue Exception => e
|
376
|
+
error {"Error while setting style of axis: #{w} -- #{e}"}
|
377
|
+
end
|
378
|
+
end
|
365
379
|
end
|
366
380
|
AxisStyleCommand.
|
367
381
|
describe("Sets the style of the given axis",
|
@@ -370,6 +384,10 @@ This command can be used to set various aspects of the style of the
|
|
370
384
|
given axis, through its various options, which are documented in more details
|
371
385
|
in the {command: define-axis-style} command -- excepted for the @ticks@ bit
|
372
386
|
which are documented in the {command: ticks} command.
|
387
|
+
|
388
|
+
If the option @also-axes@ is specified, the style is also applied to
|
389
|
+
the comma-separated list of axes it contains.
|
390
|
+
|
373
391
|
EOH
|
374
392
|
|
375
393
|
ClearAxesCommand =
|
@@ -26,7 +26,7 @@ require 'ctioga2/graphics/types/grid'
|
|
26
26
|
# This module contains all the classes used by ctioga
|
27
27
|
module CTioga2
|
28
28
|
|
29
|
-
Version::register_svn_info('$Revision:
|
29
|
+
Version::register_svn_info('$Revision: 523 $', '$Date: 2013-09-22 15:31:16 +0200 (Sun, 22 Sep 2013) $')
|
30
30
|
|
31
31
|
module Graphics
|
32
32
|
|
@@ -49,6 +49,7 @@ module CTioga2
|
|
49
49
|
|
50
50
|
ColorType = CmdType.new('color', {
|
51
51
|
:type => :tioga_color,
|
52
|
+
:namespace => Tioga::ColorConstants,
|
52
53
|
}, <<EOD)
|
53
54
|
A color. It can take three forms:
|
54
55
|
* a named color, see
|
@@ -61,9 +62,10 @@ EOD
|
|
61
62
|
ColorOrFalseType =
|
62
63
|
CmdType.new('color-or-false', {
|
63
64
|
:type => :tioga_color,
|
65
|
+
:namespace => Tioga::ColorConstants,
|
64
66
|
:shortcuts => {'none' => false }
|
65
67
|
}, <<EOD)
|
66
|
-
A {type: color}, or
|
68
|
+
A {type: color}, or none to say that nothing should be drawn.
|
67
69
|
EOD
|
68
70
|
|
69
71
|
|
data/lib/ctioga2/log.rb
CHANGED
@@ -16,7 +16,7 @@ require 'logger'
|
|
16
16
|
|
17
17
|
module CTioga2
|
18
18
|
|
19
|
-
Version::register_svn_info('$Revision:
|
19
|
+
Version::register_svn_info('$Revision: 522 $', '$Date: 2013-09-22 12:02:48 +0200 (Sun, 22 Sep 2013) $')
|
20
20
|
|
21
21
|
# This module should be included (or extended) by every class that
|
22
22
|
# need logging/debugging facilities.
|
@@ -101,7 +101,10 @@ module CTioga2
|
|
101
101
|
|
102
102
|
# A logged replacement for system
|
103
103
|
def spawn(cmd, priority = :info)
|
104
|
-
|
104
|
+
if cmd.is_a? String
|
105
|
+
cmd = [cmd]
|
106
|
+
end
|
107
|
+
retval = system(*cmd)
|
105
108
|
self.send(priority) { "Spawned #{cmd} -> " +
|
106
109
|
if retval
|
107
110
|
"success"
|
@@ -20,7 +20,7 @@ require 'ctioga2/utils'
|
|
20
20
|
|
21
21
|
module CTioga2
|
22
22
|
|
23
|
-
Version::register_svn_info('$Revision:
|
23
|
+
Version::register_svn_info('$Revision: 523 $', '$Date: 2013-09-22 15:31:16 +0200 (Sun, 22 Sep 2013) $')
|
24
24
|
|
25
25
|
|
26
26
|
# The MetaBuilder module contains a framework to perform
|
@@ -104,6 +104,13 @@ module CTioga2
|
|
104
104
|
# passed through without further modification.
|
105
105
|
attr_accessor :passthrough
|
106
106
|
|
107
|
+
# An array of module whose constants can be used "as such"
|
108
|
+
attr_accessor :namespace
|
109
|
+
|
110
|
+
# When a :namespace option is provided, this hash provides a
|
111
|
+
# lookup 'lowercase name' => constant value.
|
112
|
+
attr_accessor :namespace_lookup
|
113
|
+
|
107
114
|
# A default constructor. It should be safe to use it directly for
|
108
115
|
# children, unless something more specific is needed. Any descendent
|
109
116
|
# should *always* register _type_ as @type - or, even better, call
|
@@ -128,6 +135,7 @@ module CTioga2
|
|
128
135
|
|
129
136
|
end
|
130
137
|
|
138
|
+
|
131
139
|
# This class function actually registers the current type
|
132
140
|
# to the Type ancestor. _name_ should be a symbol.
|
133
141
|
# Moreover, if the second argument is provided, it automatically
|
@@ -200,11 +208,12 @@ module CTioga2
|
|
200
208
|
end
|
201
209
|
end
|
202
210
|
end
|
211
|
+
|
203
212
|
# Then, constants lookup.
|
204
213
|
if @type.key?(:namespace)
|
205
214
|
begin
|
206
215
|
return stt_run_hook(lookup_const(string))
|
207
|
-
rescue
|
216
|
+
rescue IncorrectInput
|
208
217
|
end
|
209
218
|
end
|
210
219
|
return stt_run_hook(string_to_type_internal(string))
|
@@ -276,17 +285,32 @@ module CTioga2
|
|
276
285
|
|
277
286
|
protected
|
278
287
|
|
288
|
+
def build_namespace_lookup
|
289
|
+
if @type[:namespace]
|
290
|
+
@namespace = [@type[:namespace]].flatten
|
291
|
+
|
292
|
+
@namespace_lookup = {}
|
293
|
+
for m in @namespace
|
294
|
+
for c in m.constants
|
295
|
+
@namespace_lookup[c.to_s.downcase] = m.const_get(c)
|
296
|
+
end
|
297
|
+
end
|
298
|
+
end
|
299
|
+
|
300
|
+
end
|
301
|
+
|
279
302
|
# Looks for the value as a constant specified in the :namespace
|
280
303
|
# modules. Raises IncorrectInput if not found.
|
281
304
|
def lookup_const(str)
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
305
|
+
str = str.downcase
|
306
|
+
if @type[:namespace] && (! @namespace_lookup)
|
307
|
+
build_namespace_lookup
|
308
|
+
end
|
309
|
+
if @namespace_lookup.key? str
|
310
|
+
return @namespace_lookup[str]
|
311
|
+
else
|
312
|
+
raise IncorrectInput, "Constant #{str} not found"
|
288
313
|
end
|
289
|
-
raise IncorrectInput, "Constant #{str} not found"
|
290
314
|
end
|
291
315
|
|
292
316
|
# The internal function for converting type to a string. Used by
|
data/lib/ctioga2/plotmaker.rb
CHANGED
@@ -158,7 +158,7 @@ require 'ctioga2/postprocess'
|
|
158
158
|
# displays of rate constants vs potentials)
|
159
159
|
module CTioga2
|
160
160
|
|
161
|
-
Version::register_svn_info('$Revision:
|
161
|
+
Version::register_svn_info('$Revision: 522 $', '$Date: 2013-09-22 12:02:48 +0200 (Sun, 22 Sep 2013) $')
|
162
162
|
|
163
163
|
# This class is the core of ctioga. It parses the command-line arguments,
|
164
164
|
# reads all necessary files and plots graphs. Most of its functionality
|
@@ -700,12 +700,18 @@ EOH
|
|
700
700
|
|
701
701
|
XpdfViewerCommand =
|
702
702
|
Cmd.new("xpdf",'-X',"--xpdf", [ ]) do |plotmaker|
|
703
|
-
plotmaker.postprocess.viewer =
|
703
|
+
plotmaker.postprocess.viewer = :auto
|
704
704
|
end
|
705
705
|
|
706
706
|
XpdfViewerCommand.describe('Uses xpdf to view the produced PDF files',
|
707
707
|
<<EOH, OutputSetupGroup)
|
708
708
|
Uses xpdf to view the PDF files produced by ctioga2.
|
709
|
+
|
710
|
+
If xpdf is not found, then it tries to guess which viewers are available:
|
711
|
+
* on windows, it uses the system file associations to open the PDF file
|
712
|
+
* on mac, it uses the open command
|
713
|
+
* on linux, it tries, mime-open, and if that is missing, falls back to
|
714
|
+
commonly available PDF viewers.
|
709
715
|
EOH
|
710
716
|
|
711
717
|
OpenViewerCommand =
|
data/lib/ctioga2/postprocess.rb
CHANGED
@@ -17,7 +17,7 @@ require 'ctioga2/log'
|
|
17
17
|
|
18
18
|
module CTioga2
|
19
19
|
|
20
|
-
Version::register_svn_info('$Revision:
|
20
|
+
Version::register_svn_info('$Revision: 522 $', '$Date: 2013-09-22 12:02:48 +0200 (Sun, 22 Sep 2013) $')
|
21
21
|
|
22
22
|
# What happens to generated PDF files ?
|
23
23
|
#
|
@@ -69,6 +69,33 @@ module CTioga2
|
|
69
69
|
end
|
70
70
|
|
71
71
|
|
72
|
+
# Try to open the file with xpdf, or fallback to system defaults
|
73
|
+
def view_pdf(pdf)
|
74
|
+
if Utils.which("xpdf")
|
75
|
+
spawn(["xpdf", "-z", "page", pdf])
|
76
|
+
else
|
77
|
+
case Utils.os
|
78
|
+
when :windows
|
79
|
+
# Use start
|
80
|
+
spawn(["start", "/B", pdf])
|
81
|
+
when :macosx
|
82
|
+
spawn(["open", pdf])
|
83
|
+
else
|
84
|
+
for w in %w{evince gv mimeopen}
|
85
|
+
if Utils.which(w)
|
86
|
+
if w == "mimeopen"
|
87
|
+
spawn(["mimeopen", "-n", pdf])
|
88
|
+
else
|
89
|
+
spawn([w, pdf])
|
90
|
+
end
|
91
|
+
break
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
|
72
99
|
# Process the given _file_. If _last_ is true, things that should
|
73
100
|
# only happen last happen.
|
74
101
|
def process_file(file, last = false)
|
@@ -96,15 +123,19 @@ module CTioga2
|
|
96
123
|
|
97
124
|
# View produced PDF or PNG files...
|
98
125
|
if (last || @view_all) && @viewer
|
99
|
-
if @
|
100
|
-
|
101
|
-
elsif @viewer =~ /%s/
|
102
|
-
cmd = @viewer % file
|
126
|
+
if @viewer == :auto
|
127
|
+
view_pdf(file)
|
103
128
|
else
|
104
|
-
|
129
|
+
if @png_res
|
130
|
+
cmd = "display #{target}"
|
131
|
+
elsif @viewer =~ /%s/
|
132
|
+
cmd = @viewer % file
|
133
|
+
else
|
134
|
+
cmd = "#{@viewer} #{file}"
|
135
|
+
end
|
136
|
+
info { "Spawning the viewer as requested for #{file}" }
|
137
|
+
spawn(cmd)
|
105
138
|
end
|
106
|
-
info { "Spawning the viewer as requested for #{file}" }
|
107
|
-
spawn(cmd)
|
108
139
|
end
|
109
140
|
end
|
110
141
|
|
data/lib/ctioga2/utils.rb
CHANGED
@@ -11,6 +11,9 @@
|
|
11
11
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
12
12
|
# GNU General Public License for more details (in the COPYING file).
|
13
13
|
|
14
|
+
# For platform detection
|
15
|
+
require 'rbconfig'
|
16
|
+
|
14
17
|
module CTioga2
|
15
18
|
|
16
19
|
# An exception to raise upon to-be-implemented-one-day features
|
@@ -35,7 +38,7 @@ module CTioga2
|
|
35
38
|
# arguments and have the Date and Revision svn:keyword:. Use this
|
36
39
|
# way:
|
37
40
|
#
|
38
|
-
# Version::register_svn_info('$Revision:
|
41
|
+
# Version::register_svn_info('$Revision: 532 $', '$Date: 2013-09-29 12:13:33 +0200 (Sun, 29 Sep 2013) $')
|
39
42
|
#
|
40
43
|
# To set the correct properties, the following command-line can be
|
41
44
|
# used:
|
@@ -75,7 +78,7 @@ module CTioga2
|
|
75
78
|
}
|
76
79
|
|
77
80
|
# The position of the URL, used for getting the version
|
78
|
-
SVN_URL = '$HeadURL: svn+ssh://rubyforge.org/var/svn/ctioga2/releases/ctioga2-0.
|
81
|
+
SVN_URL = '$HeadURL: svn+ssh://rubyforge.org/var/svn/ctioga2/releases/ctioga2-0.7/lib/ctioga2/utils.rb $'
|
79
82
|
|
80
83
|
# The version of ctioga2
|
81
84
|
CTIOGA_VERSION = if SVN_URL =~ /releases\/ctioga2-([^\/]+)/
|
@@ -84,7 +87,7 @@ module CTioga2
|
|
84
87
|
"SVN version"
|
85
88
|
end
|
86
89
|
|
87
|
-
register_svn_info('$Revision:
|
90
|
+
register_svn_info('$Revision: 532 $', '$Date: 2013-09-29 12:13:33 +0200 (Sun, 29 Sep 2013) $')
|
88
91
|
|
89
92
|
end
|
90
93
|
|
@@ -254,6 +257,93 @@ module CTioga2
|
|
254
257
|
end
|
255
258
|
return file # But that will fail later on.
|
256
259
|
end
|
260
|
+
|
261
|
+
|
262
|
+
|
263
|
+
# Cross-platform way of finding an executable in the $PATH.
|
264
|
+
#
|
265
|
+
# This is adapted from
|
266
|
+
# http://stackoverflow.com/questions/2108727/which-in-ruby-checking-if-program-exists-in-path-from-ruby
|
267
|
+
def self.which(cmd)
|
268
|
+
return nil unless cmd
|
269
|
+
exts = ['']
|
270
|
+
if ENV['PATHEXT']
|
271
|
+
exts += ENV['PATHEXT'].split(';')
|
272
|
+
end
|
273
|
+
|
274
|
+
ENV['PATH'].split(File::PATH_SEPARATOR).each do |path|
|
275
|
+
exts.each { |ext|
|
276
|
+
exe = File.join(path, "#{cmd}#{ext}")
|
277
|
+
return exe if File.executable? exe
|
278
|
+
}
|
279
|
+
end
|
280
|
+
return nil
|
281
|
+
end
|
282
|
+
|
283
|
+
|
284
|
+
# Reliable OS detection, coming from:
|
285
|
+
#
|
286
|
+
# http://stackoverflow.com/questions/11784109/detecting-operating-systems-in-ruby
|
287
|
+
def self.os
|
288
|
+
host_os = RbConfig::CONFIG['host_os']
|
289
|
+
case host_os
|
290
|
+
when /mswin|msys|mingw|cygwin|bccwin|wince|emc/
|
291
|
+
:windows
|
292
|
+
when /darwin|mac os/
|
293
|
+
:macosx
|
294
|
+
when /linux/
|
295
|
+
:linux
|
296
|
+
when /solaris|bsd/
|
297
|
+
:unix
|
298
|
+
else
|
299
|
+
warn {"Unknown os: #{host_os.inspect}"}
|
300
|
+
:unknown
|
301
|
+
end
|
302
|
+
end
|
303
|
+
|
304
|
+
|
305
|
+
# Cluster a series of objects by the values returned by the given
|
306
|
+
# funcall. It returns an array of arrays where the elements are in
|
307
|
+
# the same order, and in each sub-array, the functions all return
|
308
|
+
# the same value
|
309
|
+
#
|
310
|
+
# @todo with block too ?
|
311
|
+
def self.cluster_by_value(list, funcall)
|
312
|
+
if list.size == 0
|
313
|
+
return []
|
314
|
+
end
|
315
|
+
ret = [ [list[0]] ]
|
316
|
+
cur = ret[0]
|
317
|
+
last = cur.first.send(funcall)
|
318
|
+
|
319
|
+
for o in list[1..-1]
|
320
|
+
val = o.send(funcall)
|
321
|
+
if last == val
|
322
|
+
cur << o
|
323
|
+
else
|
324
|
+
cur = [o]
|
325
|
+
ret << cur
|
326
|
+
last = val
|
327
|
+
end
|
328
|
+
end
|
329
|
+
|
330
|
+
return ret
|
331
|
+
end
|
332
|
+
|
333
|
+
|
334
|
+
# Returns a hash value -> [elements] in which the elements are in
|
335
|
+
# the same order
|
336
|
+
def self.sort_by_value(list, funcall)
|
337
|
+
ret = {}
|
338
|
+
|
339
|
+
for el in list
|
340
|
+
val = el.send(funcall)
|
341
|
+
ret[val] ||= []
|
342
|
+
|
343
|
+
ret[val] << el
|
344
|
+
end
|
345
|
+
return ret
|
346
|
+
end
|
257
347
|
end
|
258
348
|
|
259
349
|
|