caruby-core 1.4.9 → 1.5.1
Sign up to get free protection for your applications and to get access to all the features.
- data/History.md +48 -0
- data/lib/caruby/cli/command.rb +2 -1
- data/lib/caruby/csv/csv_mapper.rb +8 -8
- data/lib/caruby/database/persistable.rb +44 -65
- data/lib/caruby/database/persistence_service.rb +12 -9
- data/lib/caruby/database/persistifier.rb +14 -14
- data/lib/caruby/database/reader.rb +53 -51
- data/lib/caruby/database/search_template_builder.rb +9 -10
- data/lib/caruby/database/store_template_builder.rb +58 -58
- data/lib/caruby/database/writer.rb +96 -96
- data/lib/caruby/database.rb +19 -19
- data/lib/caruby/domain/attribute.rb +581 -0
- data/lib/caruby/domain/attributes.rb +615 -0
- data/lib/caruby/domain/dependency.rb +240 -0
- data/lib/caruby/domain/importer.rb +183 -0
- data/lib/caruby/domain/introspection.rb +176 -0
- data/lib/caruby/domain/inverse.rb +173 -0
- data/lib/caruby/domain/inversible.rb +1 -2
- data/lib/caruby/domain/java_attribute.rb +173 -0
- data/lib/caruby/domain/merge.rb +13 -10
- data/lib/caruby/domain/metadata.rb +141 -0
- data/lib/caruby/domain/mixin.rb +35 -0
- data/lib/caruby/domain/reference_visitor.rb +5 -3
- data/lib/caruby/domain.rb +340 -0
- data/lib/caruby/import/java.rb +29 -25
- data/lib/caruby/migration/migratable.rb +5 -5
- data/lib/caruby/migration/migrator.rb +19 -15
- data/lib/caruby/migration/resource_module.rb +1 -1
- data/lib/caruby/resource.rb +39 -30
- data/lib/caruby/util/collection.rb +94 -33
- data/lib/caruby/util/coordinate.rb +28 -2
- data/lib/caruby/util/log.rb +4 -4
- data/lib/caruby/util/module.rb +12 -28
- data/lib/caruby/util/partial_order.rb +9 -10
- data/lib/caruby/util/pretty_print.rb +46 -26
- data/lib/caruby/util/topological_sync_enumerator.rb +10 -4
- data/lib/caruby/util/transitive_closure.rb +2 -2
- data/lib/caruby/util/visitor.rb +1 -1
- data/lib/caruby/version.rb +1 -1
- data/test/lib/caruby/database/persistable_test.rb +1 -1
- data/test/lib/caruby/domain/domain_test.rb +14 -28
- data/test/lib/caruby/domain/inversible_test.rb +1 -1
- data/test/lib/caruby/import/java_test.rb +5 -0
- data/test/lib/caruby/migration/test_case.rb +0 -1
- data/test/lib/caruby/test_case.rb +9 -10
- data/test/lib/caruby/util/collection_test.rb +23 -5
- data/test/lib/caruby/util/module_test.rb +10 -14
- data/test/lib/caruby/util/partial_order_test.rb +16 -15
- data/test/lib/caruby/util/visitor_test.rb +1 -1
- data/test/lib/examples/galena/clinical_trials/migration/test_case.rb +1 -1
- metadata +16 -15
- data/History.txt +0 -44
- data/lib/caruby/domain/attribute_metadata.rb +0 -551
- data/lib/caruby/domain/java_attribute_metadata.rb +0 -183
- data/lib/caruby/domain/resource_attributes.rb +0 -565
- data/lib/caruby/domain/resource_dependency.rb +0 -217
- data/lib/caruby/domain/resource_introspection.rb +0 -160
- data/lib/caruby/domain/resource_inverse.rb +0 -151
- data/lib/caruby/domain/resource_metadata.rb +0 -155
- data/lib/caruby/domain/resource_module.rb +0 -370
- data/lib/caruby/yard/resource_metadata_handler.rb +0 -8
data/lib/caruby/resource.rb
CHANGED
@@ -4,12 +4,14 @@ require 'caruby/util/log'
|
|
4
4
|
require 'caruby/util/pretty_print'
|
5
5
|
require 'caruby/util/validation'
|
6
6
|
require 'caruby/util/collection'
|
7
|
+
require 'caruby/domain'
|
8
|
+
require 'caruby/domain/mixin'
|
7
9
|
require 'caruby/domain/merge'
|
8
10
|
require 'caruby/domain/reference_visitor'
|
9
11
|
require 'caruby/database/persistable'
|
10
12
|
require 'caruby/domain/inversible'
|
11
|
-
require 'caruby/domain/
|
12
|
-
require 'caruby/domain/
|
13
|
+
require 'caruby/domain/metadata'
|
14
|
+
require 'caruby/domain/mixin'
|
13
15
|
require 'caruby/migration/migratable'
|
14
16
|
|
15
17
|
module CaRuby
|
@@ -19,9 +21,9 @@ module CaRuby
|
|
19
21
|
module Resource
|
20
22
|
include Mergeable, Migratable, Persistable, Inversible
|
21
23
|
|
22
|
-
# JRuby
|
23
|
-
#
|
24
|
-
#
|
24
|
+
# @quirk JRuby Bug #5090 - JRuby 1.5 object_id is no longer a reserved method, and results
|
25
|
+
# in a String value rather than an Integer (cf. http://jira.codehaus.org/browse/JRUBY-5090).
|
26
|
+
# Work-around is to make a proxy object id.
|
25
27
|
#
|
26
28
|
# @return [Integer] the object id
|
27
29
|
def proxy_object_id
|
@@ -38,10 +40,9 @@ module CaRuby
|
|
38
40
|
|
39
41
|
# Sets the default attribute values for this domain object and its dependents. If this Resource
|
40
42
|
# does not have an identifier, then missing attributes are set to the values defined by
|
41
|
-
# {
|
43
|
+
# {Attributes#add_attribute_defaults}.
|
42
44
|
#
|
43
|
-
#
|
44
|
-
# rather than this method.
|
45
|
+
# Subclasses should override the private {#add_defaults_local} method rather than this method.
|
45
46
|
#
|
46
47
|
# @return [Resource] self
|
47
48
|
def add_defaults
|
@@ -61,7 +62,7 @@ module CaRuby
|
|
61
62
|
add_defaults_recursive
|
62
63
|
end
|
63
64
|
|
64
|
-
# Validates this domain object and its #{
|
65
|
+
# Validates this domain object and its #{Attributes.unproxied_savable_template_attributes}
|
65
66
|
# for completeness prior to a database create operation.
|
66
67
|
# An object without an identifer is valid if it contains a non-nil value for each mandatory property.
|
67
68
|
# Objects which have an identifier or have already been validated are skipped.
|
@@ -69,18 +70,30 @@ module CaRuby
|
|
69
70
|
# Subclasses should not override this method, but override the private {#local_validate} instead.
|
70
71
|
#
|
71
72
|
# @return [Resource] this domain object
|
72
|
-
# @raise (see #
|
73
|
+
# @raise (see #validate_local)
|
73
74
|
def validate
|
74
75
|
if identifier.nil? and not @validated then
|
75
76
|
validate_local
|
76
77
|
@validated = true
|
77
78
|
end
|
78
|
-
self.class.
|
79
|
+
self.class.unproxied_savable_template_attributes.each do |attr|
|
79
80
|
send(attr).enumerate { |dep| dep.validate }
|
80
81
|
end
|
81
82
|
self
|
82
83
|
end
|
83
84
|
|
85
|
+
# Adds the default values to this object, if it is not already fetched, and its dependents.
|
86
|
+
#
|
87
|
+
# This method is intended for use only by the {#add_defaults} method.
|
88
|
+
def add_defaults_recursive
|
89
|
+
# Add the local defaults.
|
90
|
+
# The lazy loader is enabled in order to allow subclass add_defaults_local implementations
|
91
|
+
# to pick up load-on-demand references used to set defaults.
|
92
|
+
database.lazy_loader.enable { add_defaults_local }
|
93
|
+
# add dependent defaults
|
94
|
+
each_defaults_dependent { |dep| dep.add_defaults_recursive }
|
95
|
+
end
|
96
|
+
|
84
97
|
# @return [Boolean] whether this domain object has {#searchable_attributes}
|
85
98
|
def searchable?
|
86
99
|
not searchable_attributes.nil?
|
@@ -104,11 +117,12 @@ module CaRuby
|
|
104
117
|
return key_attrs if key_searchable?(key_attrs)
|
105
118
|
end
|
106
119
|
|
107
|
-
# Returns a new domain object with the given attributes copied from this domain object.
|
108
|
-
# argument consists of either attribute Symbols or a single Enumerable
|
109
|
-
#
|
120
|
+
# Returns a new domain object with the given attributes copied from this domain object.
|
121
|
+
# The attributes argument consists of either attribute Symbols or a single Enumerable
|
122
|
+
# consisting of Symbols.
|
123
|
+
# The default attributes are the {Attributes#nondomain_attributes}.
|
110
124
|
#
|
111
|
-
# @param [<Symbol>] attributes the attributes to copy
|
125
|
+
# @param [<Symbol>, (<Symbol>)] attributes the attributes to copy
|
112
126
|
# @return [Resource] a copy of this domain object
|
113
127
|
def copy(*attributes)
|
114
128
|
if attributes.empty? then
|
@@ -121,7 +135,7 @@ module CaRuby
|
|
121
135
|
end
|
122
136
|
|
123
137
|
# Clears the given attribute value. If the current value responds to the +clear+ method,
|
124
|
-
# then the current value is cleared. Otherwise, the value is set to {
|
138
|
+
# then the current value is cleared. Otherwise, the value is set to {Metadata#empty_value}.
|
125
139
|
#
|
126
140
|
# @param [Symbol] attribute the attribute to clear
|
127
141
|
def clear_attribute(attribute)
|
@@ -199,7 +213,7 @@ module CaRuby
|
|
199
213
|
end
|
200
214
|
|
201
215
|
# Returns an attribute => value hash for the specified attributes with a non-nil, non-empty value.
|
202
|
-
# The default attributes are this domain object's class {
|
216
|
+
# The default attributes are this domain object's class {Attributes#attributes}.
|
203
217
|
# Only non-nil attributes defined by this Resource are included in the result hash.
|
204
218
|
#
|
205
219
|
# @param [<Symbol>, nil] attributes the attributes to merge
|
@@ -244,7 +258,7 @@ module CaRuby
|
|
244
258
|
end
|
245
259
|
|
246
260
|
# Returns the attributes which are required for save. This base implementation returns the
|
247
|
-
# class {
|
261
|
+
# class {Attributes#mandatory_attributes}. Subclasses can override this method
|
248
262
|
# for domain object state-specific refinements.
|
249
263
|
#
|
250
264
|
# @return [<Symbol>] the required attributes for a save operation
|
@@ -327,7 +341,7 @@ module CaRuby
|
|
327
341
|
end
|
328
342
|
|
329
343
|
# Returns the difference between this Persistable and the other Persistable for the
|
330
|
-
# given attributes. The default attributes are the {
|
344
|
+
# given attributes. The default attributes are the {Attributes#nondomain_attributes}.
|
331
345
|
#
|
332
346
|
# @param [Resource] other the domain object to compare
|
333
347
|
# @param [<Symbol>, nil] attributes the attributes to compare
|
@@ -434,7 +448,7 @@ module CaRuby
|
|
434
448
|
|
435
449
|
# Prints this domain object's content and recursively prints the referenced content.
|
436
450
|
# The optional selector block determines the attributes to print. The default is the
|
437
|
-
# {
|
451
|
+
# {Attributes#java_attributes}. The database lazy loader is disabled during
|
438
452
|
# the execution of this method. Thus, the printed content reflects the transient
|
439
453
|
# in-memory object graph rather than the persistent content.
|
440
454
|
#
|
@@ -503,14 +517,6 @@ module CaRuby
|
|
503
517
|
|
504
518
|
protected
|
505
519
|
|
506
|
-
# Adds the default values to this object, if it is not already fetched, and its dependents.
|
507
|
-
def add_defaults_recursive
|
508
|
-
# add the local defaults unless there is an identifier
|
509
|
-
add_defaults_local
|
510
|
-
# add dependent defaults
|
511
|
-
each_defaults_dependent { |dep| dep.add_defaults_recursive }
|
512
|
-
end
|
513
|
-
|
514
520
|
# Returns the required attributes for this domain object which are nil or empty.
|
515
521
|
#
|
516
522
|
# This method is in protected scope to allow the +CaTissue+ domain module to
|
@@ -697,6 +703,9 @@ module CaRuby
|
|
697
703
|
end
|
698
704
|
end
|
699
705
|
|
706
|
+
# @param [Attribute] attr_md the attribute to set
|
707
|
+
# @param [Resource] ref the inverse value
|
708
|
+
# @param [Symbol] the inverse => self writer method
|
700
709
|
def delegate_to_inverse_setter(attr_md, ref, writer)
|
701
710
|
logger.debug { "Setting #{qp} #{attr_md} by setting the #{ref.qp} inverse attribute #{attr_md.inverse}..." }
|
702
711
|
ref.send(writer, self)
|
@@ -718,7 +727,7 @@ module CaRuby
|
|
718
727
|
# Returns the Java type of the given attribute, or nil if attribute is not a Java property attribute.
|
719
728
|
def java_type(attribute)
|
720
729
|
attr_md = self.class.attribute_metadata(attribute)
|
721
|
-
attr_md.property_descriptor.property_type if
|
730
|
+
attr_md.property_descriptor.property_type if JavaAttribute === attr_md
|
722
731
|
end
|
723
732
|
|
724
733
|
# Executes the given block with the database lazy loader disabled, if any.
|
@@ -736,7 +745,7 @@ module CaRuby
|
|
736
745
|
# oldval targets. If the matcher block is given, then that block is called on the sources
|
737
746
|
# and targets. Otherwise, {Resource.match_all} is called.
|
738
747
|
#
|
739
|
-
# @param [
|
748
|
+
# @param [Attribute] attr_md the attribute to match
|
740
749
|
# @param newval the source value
|
741
750
|
# @param oldval the target value
|
742
751
|
# @yield [sources, targets] matches sources to targets
|
@@ -65,7 +65,14 @@ module Enumerable
|
|
65
65
|
end
|
66
66
|
|
67
67
|
# Returns a new Hash generated from this Enumerable with a block whose arguments include the enumerated item
|
68
|
-
# and its index.
|
68
|
+
# and its index. Every value which is {#nil_or_empty} is excluded.
|
69
|
+
#
|
70
|
+
# @example
|
71
|
+
# [1, 2, 3].to_compact_hash_with_index { |item, index| item + index } #=> { 1 => 1, 2 => 3, 3 => 5 }
|
72
|
+
# @yield [item, index] the hash value
|
73
|
+
# @yieldparam item the enumerated value
|
74
|
+
# @yieldparam index the enumeration index
|
75
|
+
# @return [Hash] this {Enumerable} converted to a hash by the given block
|
69
76
|
def to_compact_hash_with_index
|
70
77
|
hash = {}
|
71
78
|
self.each_with_index do |item, index|
|
@@ -77,38 +84,38 @@ module Enumerable
|
|
77
84
|
hash
|
78
85
|
end
|
79
86
|
|
80
|
-
# Returns whether this Enumerable iterates over at least one item.
|
81
|
-
#
|
82
87
|
# This method is functionally equivalent to +to_a.empty+ but is more concise and efficient.
|
88
|
+
#
|
89
|
+
# @return [Boolean] whether this Enumerable iterates over at least one item
|
83
90
|
def empty?
|
84
91
|
not any? { true }
|
85
92
|
end
|
86
93
|
|
87
|
-
# Returns the first enumerated item in this Enumerable, or nil if this Enumerable is empty.
|
88
|
-
#
|
89
94
|
# This method is functionally equivalent to +to_a.first+ but is more concise and efficient.
|
95
|
+
#
|
96
|
+
# @return the first enumerated item in this Enumerable, or nil if this Enumerable is empty
|
90
97
|
def first
|
91
98
|
detect { true }
|
92
99
|
end
|
93
100
|
|
94
|
-
# Returns the last enumerated item in this Enumerable, or nil if this Enumerable is empty.
|
95
|
-
#
|
96
101
|
# This method is functionally equivalent to +to_a.last+ but is more concise and efficient.
|
102
|
+
#
|
103
|
+
# @return the last enumerated item in this Enumerable, or nil if this Enumerable is empty
|
97
104
|
def last
|
98
105
|
detect { true }
|
99
106
|
end
|
100
107
|
|
101
|
-
# Returns the count of items enumerated in this Enumerable.
|
102
|
-
#
|
103
108
|
# This method is functionally equivalent to +to_a.size+ but is more concise and efficient
|
104
109
|
# for an Enumerable which does not implement the {#size} method.
|
110
|
+
#
|
111
|
+
# @return [Integer] the count of items enumerated in this Enumerable
|
105
112
|
def size
|
106
113
|
inject(0) { |size, item| size + 1 }
|
107
114
|
end
|
108
115
|
|
109
116
|
alias :length :size
|
110
117
|
|
111
|
-
#
|
118
|
+
# @return [String] the content of this Enumerable as a series using {Array#to_series}
|
112
119
|
def to_series(conjunction=nil)
|
113
120
|
to_a.to_series
|
114
121
|
end
|
@@ -157,12 +164,12 @@ module Enumerable
|
|
157
164
|
# Note, however, that unlike select, filter does not return an Array.
|
158
165
|
# The default filter block returns the passed item.
|
159
166
|
#
|
167
|
+
# @example
|
168
|
+
# [1, nil, 3].filter.to_a #=> [1, 3]
|
160
169
|
# @yield [item] filter the selection filter
|
161
170
|
# @yieldparam item the collection member to filter
|
162
171
|
# @return [Enumerable] the filtered result
|
163
|
-
|
164
|
-
# [1, nil, 3].filter.to_a #=> [1, 3]
|
165
|
-
def filter(&filter) # :yields: item
|
172
|
+
def filter(&filter)
|
166
173
|
Filter.new(self, &filter)
|
167
174
|
end
|
168
175
|
|
@@ -238,6 +245,25 @@ module Enumerable
|
|
238
245
|
Joiner.new(self, other)
|
239
246
|
end
|
240
247
|
|
248
|
+
# Sorts this collection's members with a partial sort operator, i.e. the comparison returns -1, 0, 1 or nil.
|
249
|
+
# The resulting sorted order places each non-nil comparable items in the sort order. The order of nil
|
250
|
+
# comparison items is indeterminate.
|
251
|
+
#
|
252
|
+
# #example
|
253
|
+
# [Array, Numeric, Enumerable, Set].partial_sort #=> [Array, Numeric, Set, Enumerable]
|
254
|
+
# @return [Enumerable] the items in this collection in partial sort order
|
255
|
+
def partial_sort
|
256
|
+
unless block_given? then return partial_sort { |item1, item2| item1 <=> item2 } end
|
257
|
+
sort { |item1, item2| yield(item1, item2) or 1 }
|
258
|
+
end
|
259
|
+
|
260
|
+
# Sorts this collection's members with a partial sort operator on the results of applying the block.
|
261
|
+
#
|
262
|
+
# @return [Enumerable] the items in this collection in partial sort order
|
263
|
+
def partial_sort_by
|
264
|
+
partial_sort { |item1, item2| yield(item1) <=> yield(item2) }
|
265
|
+
end
|
266
|
+
|
241
267
|
# @yield [item] the transformer on the enumerated items
|
242
268
|
# @yieldparam item an enumerated item
|
243
269
|
# @return [Enumerable] the mapped values excluding null values
|
@@ -247,6 +273,7 @@ module Enumerable
|
|
247
273
|
|
248
274
|
private
|
249
275
|
|
276
|
+
# This Filter helper class applies a selection block to a base enumeration.
|
250
277
|
class Filter
|
251
278
|
include Enumerable
|
252
279
|
|
@@ -272,7 +299,7 @@ module Enumerable
|
|
272
299
|
super
|
273
300
|
end
|
274
301
|
|
275
|
-
# Adds an item to the base Enumerable, if
|
302
|
+
# Adds an item to the base Enumerable, if this Filter's base supports it.
|
276
303
|
#
|
277
304
|
# @param item the item to add
|
278
305
|
# @return [Filter] self
|
@@ -297,6 +324,7 @@ module Enumerable
|
|
297
324
|
end
|
298
325
|
end
|
299
326
|
|
327
|
+
# This Transformer helper class applies a transformer block to a base enumeration.
|
300
328
|
class Transformer
|
301
329
|
include Enumerable
|
302
330
|
|
@@ -320,7 +348,9 @@ module Enumerable
|
|
320
348
|
end
|
321
349
|
|
322
350
|
# A MultiEnumerator iterates over several Enumerators in sequence. Unlike Array#+, MultiEnumerator reflects changes to the
|
323
|
-
# underlying enumerators
|
351
|
+
# underlying enumerators.
|
352
|
+
#
|
353
|
+
# @example
|
324
354
|
# a = [1, 2]
|
325
355
|
# b = [4, 5]
|
326
356
|
# ab = MultiEnumerator.new(a, b)
|
@@ -328,26 +358,32 @@ module Enumerable
|
|
328
358
|
# a << 3; b << 6; ab.to_a #=> [1, 2, 3, 4, 5, 6]
|
329
359
|
class MultiEnumerator
|
330
360
|
include Enumerable
|
361
|
+
|
362
|
+
# @return [<Enumerable>] the enumerated collections
|
363
|
+
attr_reader :components
|
331
364
|
|
332
|
-
#
|
365
|
+
# Initializes a new {MultiEnumerator} on the given components.
|
366
|
+
#
|
367
|
+
# @param [<Enumerable>] the component enumerators to compose
|
333
368
|
def initialize(*enums)
|
334
369
|
super()
|
335
|
-
@
|
336
|
-
@
|
370
|
+
@components = enums
|
371
|
+
@components.compact!
|
337
372
|
end
|
338
373
|
|
339
374
|
# Iterates over each of this MultiEnumerator's Enumerators in sequence.
|
340
375
|
def each
|
341
|
-
@
|
376
|
+
@components.each { |enum| enum.each { |item| yield item } }
|
342
377
|
end
|
343
378
|
end
|
344
379
|
end
|
345
380
|
|
346
|
-
# The Collector utility
|
347
|
-
#
|
381
|
+
# The Collector utility implements the {on} method to apply a block to a collection
|
382
|
+
# transitive closure.
|
348
383
|
module Collector
|
349
384
|
# Collects the result of applying the given block to the given obj.
|
350
|
-
# If obj is a collection, then collects the result of recursively calling this
|
385
|
+
# If obj is a collection, then collects the result of recursively calling this
|
386
|
+
# Collector on the enumerated members.
|
351
387
|
# If obj is nil, then returns nil.
|
352
388
|
# Otherwise, calls block on obj and returns the result.
|
353
389
|
#
|
@@ -355,6 +391,7 @@ module Collector
|
|
355
391
|
# Collector.on([1, 2, [3, 4]]) { |n| n * 2 } #=> [2, 4, [6, 8]]]
|
356
392
|
# Collector.on(nil) { |n| n * 2 } #=> nil
|
357
393
|
# Collector.on(1) { |n| n * 2 } #=> 2
|
394
|
+
# @param obj the collection or item to enumerate
|
358
395
|
def self.on(obj, &block)
|
359
396
|
obj.collection? ? obj.map { |item| on(item, &block) } : yield(obj) unless obj.nil?
|
360
397
|
end
|
@@ -366,12 +403,17 @@ class Object
|
|
366
403
|
# item in this Enumerable.
|
367
404
|
# * Otherwise, if this object is non-nil, then the the block is called on self.
|
368
405
|
# * Otherwise, this object is nil and this method is a no-op.
|
406
|
+
#
|
407
|
+
# @yield [item] the block to apply to this object
|
408
|
+
# @yieldparam item the enumerated items, or this object if it is non-nil and not an Enumerable
|
369
409
|
def enumerate(&block)
|
370
410
|
Enumerable === self ? each(&block) : yield(self) unless nil?
|
371
411
|
end
|
372
412
|
|
373
413
|
# Returns an enumerator on this Object. This default implementation returns an Enumerable::Enumerator
|
374
414
|
# on enumerate.
|
415
|
+
#
|
416
|
+
# @return [Enumerable] this object as an enumerable item
|
375
417
|
def to_enum
|
376
418
|
Enumerable::Enumerator.new(self, :enumerate)
|
377
419
|
end
|
@@ -395,8 +437,9 @@ class Flattener
|
|
395
437
|
obj.collection? ? obj.each { |item| on(item, &block) } : yield(obj) unless obj.nil?
|
396
438
|
end
|
397
439
|
|
398
|
-
#
|
399
|
-
#
|
440
|
+
# Initializes a new Flattener on the given object.
|
441
|
+
#
|
442
|
+
# @param obj the Enumerable or non-collection object
|
400
443
|
def initialize(obj)
|
401
444
|
@base = obj
|
402
445
|
end
|
@@ -416,9 +459,9 @@ class Flattener
|
|
416
459
|
end
|
417
460
|
end
|
418
461
|
|
419
|
-
# ConditionalEnumerator applies a filter to another Enumerable
|
462
|
+
# ConditionalEnumerator applies a filter to another Enumerable.
|
463
|
+
# @example
|
420
464
|
# ConditionalEnumerator.new([1, 2, 3]) { |i| i < 3 }.to_a #=> [1, 2]
|
421
|
-
#
|
422
465
|
class ConditionalEnumerator
|
423
466
|
include Enumerable
|
424
467
|
|
@@ -456,13 +499,28 @@ module Hashable
|
|
456
499
|
each { |key, value| yield key }
|
457
500
|
end
|
458
501
|
|
459
|
-
# @
|
502
|
+
# @yield [key] the detector block
|
503
|
+
# @yieldparam key the hash key
|
504
|
+
# @return [Object, nil] the key for which the detector block returns a non-nil, non-false value,
|
460
505
|
# or nil if none
|
506
|
+
# @example
|
507
|
+
# {1 => :a, 2 => :b, 3 => :c}.detect_key { |k| k > 1 } #=> 2
|
461
508
|
def detect_key
|
462
509
|
each_key { |key| return key if yield key }
|
463
510
|
nil
|
464
511
|
end
|
465
512
|
|
513
|
+
# @yield [value] the detector block
|
514
|
+
# @yieldparam value the hash value
|
515
|
+
# @return [Object, nil] the key for which the detector block returns a non-nil, non-false value,
|
516
|
+
# or nil if none
|
517
|
+
# @example
|
518
|
+
# {:a => 1, :b => 2, :c => 3}.detect_key_with_value { |v| v > 1 } #=> :b
|
519
|
+
def detect_key_with_value
|
520
|
+
each { |key, value| return key if yield value }
|
521
|
+
nil
|
522
|
+
end
|
523
|
+
|
466
524
|
# @see Hash#each_value
|
467
525
|
def each_value
|
468
526
|
each { |key, value| yield value }
|
@@ -793,29 +851,32 @@ module Hashable
|
|
793
851
|
# Combines hashes. See Hash#+ for details.
|
794
852
|
class MultiHash
|
795
853
|
include Hashable
|
854
|
+
|
855
|
+
# @return [<Hashable>] the enumerated hashes
|
856
|
+
attr_reader :components
|
796
857
|
|
797
858
|
def initialize(*hashes)
|
798
859
|
if hashes.include?(nil) then raise ArgumentError.new("MultiHash is missing a component hash.") end
|
799
|
-
@
|
860
|
+
@components = hashes
|
800
861
|
end
|
801
862
|
|
802
863
|
def [](key)
|
803
|
-
@
|
864
|
+
@components.each { |hash| return hash[key] if hash.has_key?(key) }
|
804
865
|
nil
|
805
866
|
end
|
806
867
|
|
807
868
|
def has_key?(key)
|
808
|
-
@
|
869
|
+
@components.any? { |hash| hash.has_key?(key) }
|
809
870
|
end
|
810
871
|
|
811
872
|
def has_value?(value)
|
812
|
-
@
|
873
|
+
@components.any? { |hash| hash.has_value?(value) }
|
813
874
|
end
|
814
875
|
|
815
876
|
def each
|
816
|
-
@
|
877
|
+
@components.each_with_index do |hash, index|
|
817
878
|
hash.each do |key, value|
|
818
|
-
yield(key, value) unless (0...index).any? { |i| @
|
879
|
+
yield(key, value) unless (0...index).any? { |i| @components[i].has_key?(key) }
|
819
880
|
end
|
820
881
|
end
|
821
882
|
self
|
@@ -1,4 +1,4 @@
|
|
1
|
-
# JRuby
|
1
|
+
# JRuby SyncEnumerator moved from generator to REXML in JRuby 1.5
|
2
2
|
require 'rexml/document'
|
3
3
|
|
4
4
|
# A Coordinate is a convenience Array wrapper class with aliased #x, #y and {#z} dimensions.
|
@@ -41,22 +41,48 @@ class Coordinate < Array
|
|
41
41
|
self[2] = value
|
42
42
|
end
|
43
43
|
|
44
|
+
# @param [Coordinate] other the coordinate to compare
|
44
45
|
# @return [Boolean] whether other is a Coordinate and has the same content as this Coordinate
|
45
46
|
def ==(other)
|
46
47
|
super rescue false
|
47
48
|
end
|
49
|
+
|
50
|
+
# @param (see #==)
|
51
|
+
# @return [Boolean] the comparison result
|
52
|
+
def <(other)
|
53
|
+
(self <=> other) < 0
|
54
|
+
end
|
55
|
+
|
56
|
+
# @param (see #==)
|
57
|
+
# @return (see #<)
|
58
|
+
def <=(other)
|
59
|
+
(self <=> other) <= 0
|
60
|
+
end
|
61
|
+
|
62
|
+
# @param (see #==)
|
63
|
+
# @return (see #<)
|
64
|
+
def >(other)
|
65
|
+
(self <=> other) > 0
|
66
|
+
end
|
67
|
+
|
68
|
+
# @param (see #==)
|
69
|
+
# @return (see #<)
|
70
|
+
def >=(other)
|
71
|
+
(self <=> other) >= 0
|
72
|
+
end
|
48
73
|
|
49
74
|
# Returns the comparison of the highest dimension which differs from the other
|
50
75
|
# coordinate, or zero if all dimensions are the same. This comparator sorts
|
51
76
|
# coordinates in z-y-x order.
|
52
77
|
# @example
|
53
78
|
# Coordinate.new(2, 1) < Coordinate.new(1, 2) #=> true
|
79
|
+
# @param [Coordinate] other the coordinate to compare
|
54
80
|
# @return [Integer] the high-to-low dimension comparison
|
55
81
|
# @raise [ArgumentError] if this Coordinate dimension size Coordinate differs from that
|
56
82
|
# of the other Dimension or any of the dimension values are nil
|
57
83
|
# @raise [TypeError] if other is not a Coordinate
|
58
84
|
def <=>(other)
|
59
|
-
return
|
85
|
+
return 0 if equal?(other)
|
60
86
|
raise TypeError.new("Can't compare #{self} with #{other} since it is not a Coordinate") unless Coordinate === other
|
61
87
|
raise ArgumentError.new("Can't compare #{self} with #{other} since it has a different dimension count") unless size == other.size
|
62
88
|
REXML::SyncEnumerator.new(self.reverse, other.reverse).each_with_index do |pair, index|
|
data/lib/caruby/util/log.rb
CHANGED
@@ -5,7 +5,7 @@ require 'caruby/util/collection'
|
|
5
5
|
|
6
6
|
# @return [CaRuby::Logger] the global logger
|
7
7
|
def logger
|
8
|
-
CaRuby::Log
|
8
|
+
CaRuby::Log.instance.logger
|
9
9
|
end
|
10
10
|
|
11
11
|
module CaRuby
|
@@ -50,7 +50,7 @@ module CaRuby
|
|
50
50
|
shift_age = Options.get(:shift_age, options, 4)
|
51
51
|
shift_size = Options.get(:shift_size, options, 16 * 1048576)
|
52
52
|
@logger = MultilineLogger.new(dev, shift_age, shift_size)
|
53
|
-
@logger.level = Options.get(:debug, options) ? Logger::DEBUG : Logger::INFO
|
53
|
+
@logger.level = Options.get(:debug, options, ENV['DEBUG']) ? Logger::DEBUG : Logger::INFO
|
54
54
|
@logger.info('============================================')
|
55
55
|
@logger.info('Logging started.')
|
56
56
|
@dev = dev
|
@@ -83,8 +83,8 @@ module CaRuby
|
|
83
83
|
log_ndx = ARGV.index("--log") || ARGV.index("-l")
|
84
84
|
if log_ndx then
|
85
85
|
ARGV[log_ndx + 1]
|
86
|
-
elsif ENV.has_key?("
|
87
|
-
ENV["
|
86
|
+
elsif ENV.has_key?("LOG") then
|
87
|
+
ENV["LOG"]
|
88
88
|
elsif defined?(DEF_LOG_FILE)
|
89
89
|
DEF_LOG_FILE
|
90
90
|
else
|
data/lib/caruby/util/module.rb
CHANGED
@@ -1,34 +1,18 @@
|
|
1
1
|
class Module
|
2
|
-
# Returns the class or module with name in
|
3
|
-
#
|
4
|
-
# Otherwise, this method returns {#module_with_name}.
|
5
|
-
def self.module_with_name(parent, name)
|
6
|
-
return parent.module_with_name(name) if parent
|
7
|
-
begin
|
8
|
-
constant = eval(name)
|
9
|
-
rescue Exception
|
10
|
-
return
|
11
|
-
end
|
12
|
-
constant if constant.is_a?(Module)
|
13
|
-
end
|
14
|
-
|
15
|
-
# Returns the class or module with name in this module.
|
16
|
-
# name can qualified by parent modules, e.g. +MyApp::Person+.
|
2
|
+
# Returns the class or module with the given name defined in this module.
|
3
|
+
# The name can qualified by parent modules, e.g. +MyApp::Person+.
|
17
4
|
# If name cannot be resolved as a Module, then this method returns nil.
|
5
|
+
#
|
6
|
+
# @param [String] the class name
|
7
|
+
# @return [Module, nil] the class or module defined in this module, or nil if none
|
18
8
|
def module_with_name(name)
|
19
|
-
|
20
|
-
constant = name.split('::').inject(parent) { |parent, name| parent.const_get(name) }
|
21
|
-
rescue Exception
|
22
|
-
return
|
23
|
-
end
|
24
|
-
constant if constant.is_a?(Module)
|
9
|
+
name.split('::').inject(self) { |parent, part| parent.const_get(part) } rescue nil
|
25
10
|
end
|
26
|
-
|
27
|
-
#
|
28
|
-
#
|
29
|
-
#
|
30
|
-
def
|
31
|
-
|
32
|
-
mod if mod.is_a?(Class)
|
11
|
+
|
12
|
+
# @example
|
13
|
+
# A::B.parent_module #=> A
|
14
|
+
# @return [Module] this module's definition context
|
15
|
+
def parent_module
|
16
|
+
Kernel.module_with_name(name.split('::')[0..-2].join('::'))
|
33
17
|
end
|
34
18
|
end
|
@@ -9,7 +9,6 @@
|
|
9
9
|
# module Queued
|
10
10
|
# attr_reader :queue
|
11
11
|
# def <=>(other)
|
12
|
-
# raise TypeError.new("Comparison argument is not another Queued item") unless Queued === other
|
13
12
|
# queue.index(self) <=> queue.index(other) if queue.equal?(other.queue)
|
14
13
|
# end
|
15
14
|
# end
|
@@ -19,18 +18,18 @@
|
|
19
18
|
# b < c #=> nil
|
20
19
|
module PartialOrder
|
21
20
|
include Comparable
|
22
|
-
|
21
|
+
|
23
22
|
Comparable.instance_methods(false).each do |m|
|
24
23
|
define_method(m.to_sym) do |other|
|
25
24
|
self <=> other ? super : nil
|
26
25
|
end
|
27
|
-
|
28
|
-
# Returns true if other is an instance of this object's class and other == self,
|
29
|
-
# false otherwise.
|
30
|
-
def eql?(other)
|
31
|
-
self.class === other and super
|
32
|
-
end
|
33
|
-
|
34
|
-
alias :== :eql?
|
35
26
|
end
|
27
|
+
|
28
|
+
# @return [Boolean] true if other is an instance of this object's class and other == self,
|
29
|
+
# false otherwise
|
30
|
+
def eql?(other)
|
31
|
+
self.class === other and super
|
32
|
+
end
|
33
|
+
|
34
|
+
alias :== :eql?
|
36
35
|
end
|