caruby-core 1.4.9 → 1.5.1
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/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
|