utilrb 3.1.0 → 3.2.0
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.
- checksums.yaml +5 -5
- data/lib/utilrb/event_loop.rb +51 -49
- data/lib/utilrb/exception/full_message.rb +2 -1
- data/lib/utilrb/hash/slice.rb +2 -5
- data/lib/utilrb/kernel/options.rb +3 -4
- data/lib/utilrb/logger/hierarchy.rb +36 -17
- data/lib/utilrb/module/dsl_attribute.rb +37 -25
- data/lib/utilrb/object/address.rb +15 -3
- data/lib/utilrb/object/attribute.rb +2 -1
- data/lib/utilrb/pkgconfig.rb +190 -101
- data/lib/utilrb/thread_pool.rb +29 -25
- data/lib/utilrb/version.rb +1 -1
- data/manifest.xml +1 -0
- data/utilrb.gemspec +1 -0
- metadata +20 -8
- data/.travis.yml +0 -11
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
|
-
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: e7c52ce8cf8f86508f209e723a1dc3db6b0f6715cf16c241a8040513d4be8075
|
|
4
|
+
data.tar.gz: e9d068b547eed7e0343ca896006546824da96ba5615d8ef90e75a0b5b4856678
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: a89739a884d6acbb494a868eb93e4b0510deda9f5ce5aae6553ca31810434ba79e5bf267ab9b242e96ac13f9f9bb25cf2e18b83b543fb8bbbbd7a693a0e98d8c
|
|
7
|
+
data.tar.gz: 8f09934f484ceadaf67c6be2a089f776f94040164e11de00890ed9075818818687f5864a2f6b6d39a1119a9acadb58f01afe2936c27348ce428743f070f27fd7
|
data/lib/utilrb/event_loop.rb
CHANGED
|
@@ -4,7 +4,7 @@ require 'utilrb/thread_pool'
|
|
|
4
4
|
module Utilrb
|
|
5
5
|
# Simple event loop which supports timers and defers blocking operations to
|
|
6
6
|
# a thread pool those results are queued and being processed by the event
|
|
7
|
-
# loop thread at the end of each step.
|
|
7
|
+
# loop thread at the end of each step.
|
|
8
8
|
#
|
|
9
9
|
# All events must be code blocks which will be executed at the end of each step.
|
|
10
10
|
# There is no support for filtering or event propagations.
|
|
@@ -13,17 +13,17 @@ module Utilrb
|
|
|
13
13
|
# can be used.
|
|
14
14
|
#
|
|
15
15
|
# @example Example for using the EventLoop
|
|
16
|
-
# event_loop = EventLoop.new
|
|
17
|
-
# event_loop.once do
|
|
16
|
+
# event_loop = EventLoop.new
|
|
17
|
+
# event_loop.once do
|
|
18
18
|
# puts "called once"
|
|
19
19
|
# end
|
|
20
20
|
#
|
|
21
|
-
# event_loop.every(1.0) do
|
|
21
|
+
# event_loop.every(1.0) do
|
|
22
22
|
# puts "called every second"
|
|
23
23
|
# end
|
|
24
24
|
#
|
|
25
25
|
# callback = Proc.new |result|
|
|
26
|
-
# puts result
|
|
26
|
+
# puts result
|
|
27
27
|
# end
|
|
28
28
|
# event_loop.defer callback do
|
|
29
29
|
# sleep 2
|
|
@@ -31,14 +31,14 @@ module Utilrb
|
|
|
31
31
|
# end
|
|
32
32
|
#
|
|
33
33
|
# event_loop.exec
|
|
34
|
-
#
|
|
34
|
+
#
|
|
35
35
|
# @author Alexander Duda <Alexander.Duda@dfki.de>
|
|
36
36
|
class EventLoop
|
|
37
37
|
# Timer for the {EventLoop} which supports single shot and periodic activation
|
|
38
38
|
#
|
|
39
39
|
# @example
|
|
40
40
|
# loop = EventLoop.new
|
|
41
|
-
# timer = EventLoop.every(0.1) do
|
|
41
|
+
# timer = EventLoop.every(0.1) do
|
|
42
42
|
# puts 123
|
|
43
43
|
# end
|
|
44
44
|
# loop.exec
|
|
@@ -52,15 +52,15 @@ module Utilrb
|
|
|
52
52
|
# A timer
|
|
53
53
|
#
|
|
54
54
|
# @param [EventLoop] event_loop the {EventLoop} the timer belongs to
|
|
55
|
-
# @param[Float] period The period of the timer in seconds.
|
|
56
|
-
# @param[Boolean] single_shot if true the timer will fire only once
|
|
57
|
-
# @param[#call] block The code block which will be executed each time the timer fires
|
|
55
|
+
# @param [Float] period The period of the timer in seconds.
|
|
56
|
+
# @param [Boolean] single_shot if true the timer will fire only once
|
|
57
|
+
# @param [#call] block The code block which will be executed each time the timer fires
|
|
58
58
|
# @see EventLoop#once
|
|
59
59
|
def initialize(event_loop,period=0,single_shot=false,&block)
|
|
60
60
|
@block = block
|
|
61
61
|
@event_loop = event_loop
|
|
62
62
|
@last_call = Time.now
|
|
63
|
-
@period = period
|
|
63
|
+
@period = Float(period)
|
|
64
64
|
@single_shot = single_shot
|
|
65
65
|
@stopped = true
|
|
66
66
|
@doc = Kernel.caller.find do |s|
|
|
@@ -75,7 +75,7 @@ module Utilrb
|
|
|
75
75
|
end
|
|
76
76
|
|
|
77
77
|
def stopped?
|
|
78
|
-
@stopped
|
|
78
|
+
@stopped
|
|
79
79
|
end
|
|
80
80
|
|
|
81
81
|
# Returns true if the timer is currently running.
|
|
@@ -128,7 +128,7 @@ module Utilrb
|
|
|
128
128
|
@single_shot == true
|
|
129
129
|
end
|
|
130
130
|
|
|
131
|
-
# Executes the code block tight to the timer and
|
|
131
|
+
# Executes the code block tight to the timer and
|
|
132
132
|
# saves a time stamp.
|
|
133
133
|
#
|
|
134
134
|
# @param [Time] time The time stamp
|
|
@@ -163,7 +163,7 @@ module Utilrb
|
|
|
163
163
|
def ignore!
|
|
164
164
|
@ignore = true
|
|
165
165
|
end
|
|
166
|
-
|
|
166
|
+
|
|
167
167
|
def ignore?
|
|
168
168
|
@ignore
|
|
169
169
|
end
|
|
@@ -242,7 +242,7 @@ module Utilrb
|
|
|
242
242
|
# queue the call if the task blocks for ever and it will never simultaneously
|
|
243
243
|
# defer the call to more than one worker thread.
|
|
244
244
|
#
|
|
245
|
-
# @param [Hash] options The options
|
|
245
|
+
# @param [Hash] options The options
|
|
246
246
|
# @option options [Float] :period The period
|
|
247
247
|
# @option options [Boolean] :start Starts the timer right away (default = true)
|
|
248
248
|
# @param [#call] work The proc which will be deferred
|
|
@@ -286,12 +286,12 @@ module Utilrb
|
|
|
286
286
|
# else
|
|
287
287
|
# puts r
|
|
288
288
|
# end
|
|
289
|
-
# end
|
|
289
|
+
# end
|
|
290
290
|
# defer({:callback => callback}) do
|
|
291
291
|
# raise
|
|
292
292
|
# end
|
|
293
293
|
#
|
|
294
|
-
# @param [Hash] options The options
|
|
294
|
+
# @param [Hash] options The options
|
|
295
295
|
# @option (see ThreadPool::Task#initialize)
|
|
296
296
|
# @option options [Proc] :callback The callback
|
|
297
297
|
# @option options [class] :known_errors Known erros which will be rescued
|
|
@@ -344,9 +344,7 @@ module Utilrb
|
|
|
344
344
|
end
|
|
345
345
|
end
|
|
346
346
|
end
|
|
347
|
-
|
|
348
|
-
@thread_pool << task
|
|
349
|
-
end
|
|
347
|
+
add_task task
|
|
350
348
|
task
|
|
351
349
|
end
|
|
352
350
|
|
|
@@ -358,6 +356,7 @@ module Utilrb
|
|
|
358
356
|
# @return [Utilrb::EventLoop::Timer,Event]
|
|
359
357
|
def once(delay=nil,&block)
|
|
360
358
|
raise ArgumentError "no block given" unless block
|
|
359
|
+
|
|
361
360
|
if delay && delay > 0
|
|
362
361
|
timer = Timer.new(self,delay,true,&block)
|
|
363
362
|
timer.start(timer.period, false)
|
|
@@ -368,7 +367,7 @@ module Utilrb
|
|
|
368
367
|
|
|
369
368
|
# Calls the give block in the event loop thread. If the current thread
|
|
370
369
|
# is the event loop thread it will execute it right a way and returns
|
|
371
|
-
# the result of the code block call. Otherwise, it returns an handler to
|
|
370
|
+
# the result of the code block call. Otherwise, it returns an handler to
|
|
372
371
|
# the Event which was queued.
|
|
373
372
|
#
|
|
374
373
|
#@return [Event,Object]
|
|
@@ -387,7 +386,7 @@ module Utilrb
|
|
|
387
386
|
!@events.empty? || !@errors.empty?
|
|
388
387
|
end
|
|
389
388
|
|
|
390
|
-
# Adds a timer to the event loop which will execute
|
|
389
|
+
# Adds a timer to the event loop which will execute
|
|
391
390
|
# the given code block with the given period from the
|
|
392
391
|
# event loop thread.
|
|
393
392
|
#
|
|
@@ -422,7 +421,7 @@ module Utilrb
|
|
|
422
421
|
end
|
|
423
422
|
|
|
424
423
|
# Errors caught during event loop callbacks are forwarded to
|
|
425
|
-
# registered code blocks. The code blocks are called from
|
|
424
|
+
# registered code blocks. The code blocks are called from
|
|
426
425
|
# the event loop thread.
|
|
427
426
|
#
|
|
428
427
|
# @param @error_classes The error classes the block should be called for
|
|
@@ -442,7 +441,7 @@ module Utilrb
|
|
|
442
441
|
raise "current thread is not the event loop thread" if !thread?
|
|
443
442
|
end
|
|
444
443
|
|
|
445
|
-
# Returns true if the current thread is the
|
|
444
|
+
# Returns true if the current thread is the
|
|
446
445
|
# event loop thread.
|
|
447
446
|
#
|
|
448
447
|
# @return [Boolean]
|
|
@@ -487,7 +486,7 @@ module Utilrb
|
|
|
487
486
|
|
|
488
487
|
# Cancels the given timer if it is running otherwise
|
|
489
488
|
# it does nothing.
|
|
490
|
-
#
|
|
489
|
+
#
|
|
491
490
|
# @param [Timer] timer The timer
|
|
492
491
|
def cancel_timer(timer)
|
|
493
492
|
@mutex.synchronize do
|
|
@@ -495,12 +494,12 @@ module Utilrb
|
|
|
495
494
|
end
|
|
496
495
|
end
|
|
497
496
|
|
|
498
|
-
# Resets all timers to fire not before their hole
|
|
497
|
+
# Resets all timers to fire not before their hole
|
|
499
498
|
# period is passed counting from the given point in time.
|
|
500
499
|
#
|
|
501
500
|
# @param [Time] time The time
|
|
502
501
|
def reset_timers(time = Time.now)
|
|
503
|
-
@mutex.synchronize do
|
|
502
|
+
@mutex.synchronize do
|
|
504
503
|
@timers.each do |timer|
|
|
505
504
|
timer.reset time
|
|
506
505
|
end
|
|
@@ -529,10 +528,12 @@ module Utilrb
|
|
|
529
528
|
@stop = true
|
|
530
529
|
end
|
|
531
530
|
|
|
532
|
-
|
|
531
|
+
class WaitForTimeout < RuntimeError; end
|
|
532
|
+
|
|
533
|
+
# Steps with the given period until the given
|
|
533
534
|
# block returns true.
|
|
534
535
|
#
|
|
535
|
-
# @param [Float] period The period
|
|
536
|
+
# @param [Float] period The period
|
|
536
537
|
# @param [Float] timeout The timeout in seconds
|
|
537
538
|
# @yieldreturn [Boolean]
|
|
538
539
|
def wait_for(period=0.05,timeout=nil,&block)
|
|
@@ -541,7 +542,7 @@ module Utilrb
|
|
|
541
542
|
exec period do
|
|
542
543
|
stop if block.call
|
|
543
544
|
if timeout && timeout <= (Time.now-start).to_f
|
|
544
|
-
raise
|
|
545
|
+
raise WaitForTimeout,"timed out during wait_for"
|
|
545
546
|
end
|
|
546
547
|
end
|
|
547
548
|
@stop = old_stop
|
|
@@ -587,7 +588,7 @@ module Utilrb
|
|
|
587
588
|
validate_thread
|
|
588
589
|
reraise_error(@errors.shift) if !@errors.empty?
|
|
589
590
|
|
|
590
|
-
#copy all work otherwise it would not be allowed to
|
|
591
|
+
#copy all work otherwise it would not be allowed to
|
|
591
592
|
#call any event loop functions from a timer
|
|
592
593
|
timers,call = @mutex.synchronize do
|
|
593
594
|
@every_cylce_events.delete_if(&:ignore?)
|
|
@@ -620,7 +621,7 @@ module Utilrb
|
|
|
620
621
|
end
|
|
621
622
|
handle_errors{call.call} if call
|
|
622
623
|
reraise_error(@errors.shift) if !@errors.empty?
|
|
623
|
-
|
|
624
|
+
|
|
624
625
|
#allow thread pool to take over
|
|
625
626
|
Thread.pass
|
|
626
627
|
end
|
|
@@ -655,7 +656,9 @@ module Utilrb
|
|
|
655
656
|
#
|
|
656
657
|
# @param [ThreadPool::Task] task The task.
|
|
657
658
|
def add_task(task)
|
|
658
|
-
|
|
659
|
+
@mutex.synchronize do
|
|
660
|
+
@thread_pool << task
|
|
661
|
+
end
|
|
659
662
|
end
|
|
660
663
|
|
|
661
664
|
# Clears all timers, events and errors
|
|
@@ -670,29 +673,28 @@ module Utilrb
|
|
|
670
673
|
end
|
|
671
674
|
end
|
|
672
675
|
|
|
673
|
-
# Clears all errors which occurred during the last step and are not marked as known
|
|
676
|
+
# Clears all errors which occurred during the last step and are not marked as known
|
|
674
677
|
# If the errors were not cleared they are re raised the next time step is called.
|
|
675
678
|
def clear_errors
|
|
676
679
|
@errors.clear
|
|
677
680
|
end
|
|
678
681
|
|
|
679
|
-
def handle_error(error,save = true)
|
|
682
|
+
def handle_error(error, save = true)
|
|
683
|
+
@errors << error if save
|
|
684
|
+
|
|
680
685
|
call do
|
|
681
|
-
on_error = @
|
|
682
|
-
@on_error.find_all{|key,e| error.is_a? key}.map(&:last).flatten
|
|
683
|
-
end
|
|
686
|
+
on_error = @on_error.find_all{|key,e| error.is_a? key}.map(&:last).flatten
|
|
684
687
|
on_error.each do |handler|
|
|
685
688
|
handler.call error
|
|
686
689
|
end
|
|
687
|
-
@errors << error if save == true
|
|
688
690
|
end
|
|
689
691
|
end
|
|
690
692
|
|
|
691
693
|
private
|
|
692
694
|
# Calls the given block and rescues all errors which can be handled
|
|
693
|
-
# by the added error handler. If an error cannot be handled it is
|
|
695
|
+
# by the added error handler. If an error cannot be handled it is
|
|
694
696
|
# stored and re raised after all events and timers are processed. If
|
|
695
|
-
# more than one error occurred which cannot be handled they are stored
|
|
697
|
+
# more than one error occurred which cannot be handled they are stored
|
|
696
698
|
# until the next step is called and re raised until all errors are processed.
|
|
697
699
|
#
|
|
698
700
|
# @info This method must be called from the event loop thread, otherwise
|
|
@@ -741,7 +743,7 @@ module Utilrb
|
|
|
741
743
|
# accessor.method(*args) but called from a thread pool. Thereby the code
|
|
742
744
|
# block is used as callback called from the main thread after the
|
|
743
745
|
# call returned. If an error occurred it will be:
|
|
744
|
-
# * given to the callback as second argument
|
|
746
|
+
# * given to the callback as second argument
|
|
745
747
|
# * forwarded to the error handlers of the event loop
|
|
746
748
|
# * raised at the beginning of the next step if not marked as known error
|
|
747
749
|
#
|
|
@@ -759,17 +761,17 @@ module Utilrb
|
|
|
759
761
|
# end
|
|
760
762
|
#
|
|
761
763
|
# ali do |result,exception|
|
|
762
|
-
# if exception
|
|
764
|
+
# if exception
|
|
763
765
|
# :ignore_error
|
|
764
766
|
# else
|
|
765
767
|
# puts result
|
|
766
768
|
# end
|
|
767
769
|
# end
|
|
768
770
|
#
|
|
769
|
-
# If the callback accepts only one argument
|
|
771
|
+
# If the callback accepts only one argument
|
|
770
772
|
# the callback will not be called in an event of an error but
|
|
771
773
|
# the error will still be forwarded to the error handlers.
|
|
772
|
-
#
|
|
774
|
+
#
|
|
773
775
|
# If the result shall be filtered before returned a filter method can
|
|
774
776
|
# be specified which is called from the event loop thread just before
|
|
775
777
|
# the result is returned.
|
|
@@ -816,7 +818,7 @@ module Utilrb
|
|
|
816
818
|
# @param [Symbol] method The method called on the designated object.
|
|
817
819
|
# @param [Hash] options The options
|
|
818
820
|
# @option options [Symbol] :alias The alias of the method
|
|
819
|
-
# @option options [Symbol] :sync_key The sync key
|
|
821
|
+
# @option options [Symbol] :sync_key The sync key
|
|
820
822
|
# @option options [Symbol] :filter The filter method
|
|
821
823
|
# @option options [Symbol] :on_error Method which is called if an error occured
|
|
822
824
|
# @option options [class] :known_errors Known errors which will be rescued but still be forwarded.
|
|
@@ -845,12 +847,12 @@ module Utilrb
|
|
|
845
847
|
|
|
846
848
|
def options(options = Hash.new,&block)
|
|
847
849
|
@stack << @stack.last.merge(options)
|
|
848
|
-
|
|
850
|
+
block.call
|
|
849
851
|
@stack.pop
|
|
850
852
|
end
|
|
851
853
|
|
|
852
854
|
def thread_safe(&block)
|
|
853
|
-
options :sync_key => nil do
|
|
855
|
+
options :sync_key => nil do
|
|
854
856
|
block.call
|
|
855
857
|
end
|
|
856
858
|
end
|
|
@@ -949,7 +951,7 @@ module Utilrb
|
|
|
949
951
|
end
|
|
950
952
|
end
|
|
951
953
|
|
|
952
|
-
# Defines multiple method as delegator instance methods
|
|
954
|
+
# Defines multiple method as delegator instance methods
|
|
953
955
|
# @see #def_event_loop_delegator
|
|
954
956
|
def self.def_event_loop_delegators(klass,accessor,event_loop, *methods)
|
|
955
957
|
methods.flatten!
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
require 'utilrb/kernel/options'
|
|
2
2
|
|
|
3
|
+
unless Exception.method_defined?(:full_message)
|
|
3
4
|
class Exception
|
|
4
5
|
# Returns the full exception message, with backtrace, like the one we get from
|
|
5
6
|
# the Ruby interpreter when the program is aborted (well, almost like that)
|
|
@@ -53,4 +54,4 @@ class Exception
|
|
|
53
54
|
msg
|
|
54
55
|
end
|
|
55
56
|
end
|
|
56
|
-
|
|
57
|
+
end
|
data/lib/utilrb/hash/slice.rb
CHANGED
|
@@ -1,6 +1,3 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
keys.inject({}) { |h, k| h[k] = self[k] if has_key?(k); h }
|
|
4
|
-
end
|
|
5
|
-
end
|
|
1
|
+
STDERR.puts "[DEPRECATED] utilrb/hash/slice is deprecated, use backports' backports/2.5.0/hash/slice instead or the built-in method in Ruby >= 2.5"
|
|
2
|
+
require 'backports/2.5.0/hash/slice'
|
|
6
3
|
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
require 'utilrb/hash/to_sym_keys'
|
|
2
|
-
require 'utilrb/hash/slice'
|
|
3
2
|
module Kernel
|
|
4
3
|
def filter_options_handle_single_entry(known_options, options, key)
|
|
5
4
|
key = key.to_sym
|
|
@@ -60,11 +59,11 @@ module Kernel
|
|
|
60
59
|
end
|
|
61
60
|
|
|
62
61
|
# Validates an option hash, with default value support. See #filter_options
|
|
63
|
-
#
|
|
64
|
-
# In the first form, +option_hash+ should contain keys which are also
|
|
62
|
+
#
|
|
63
|
+
# In the first form, +option_hash+ should contain keys which are also
|
|
65
64
|
# in known_hash. The non-nil values of +known_hash+ are used as default
|
|
66
65
|
# values. In the second form, +known_array+ is an array of option
|
|
67
|
-
# keys. +option_hash+ keys shall be in +known_array+. +nil+ is treated
|
|
66
|
+
# keys. +option_hash+ keys shall be in +known_array+. +nil+ is treated
|
|
68
67
|
# as an empty option hash, all keys are converted into symbols.
|
|
69
68
|
#
|
|
70
69
|
def validate_options(options, *known_options)
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
require 'facets/module/spacename'
|
|
2
|
-
require 'facets/kernel/constant'
|
|
3
2
|
require 'utilrb/object/attribute'
|
|
4
3
|
require 'utilrb/logger/forward'
|
|
5
4
|
require 'weakref'
|
|
@@ -28,6 +27,16 @@ class Logger
|
|
|
28
27
|
log_children << WeakRef.new(child)
|
|
29
28
|
end
|
|
30
29
|
|
|
30
|
+
def deregister_log_child(child)
|
|
31
|
+
log_children.delete_if do |ref|
|
|
32
|
+
begin
|
|
33
|
+
ref.__getobj__ == child
|
|
34
|
+
rescue WeakRef::RefError
|
|
35
|
+
true
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
31
40
|
def each_log_child
|
|
32
41
|
return enum_for(__method__) if !block_given?
|
|
33
42
|
|
|
@@ -41,36 +50,47 @@ class Logger
|
|
|
41
50
|
end
|
|
42
51
|
end
|
|
43
52
|
|
|
53
|
+
# @api private
|
|
54
|
+
#
|
|
55
|
+
# Resets the default logger of this context's children
|
|
56
|
+
#
|
|
57
|
+
# This is called whenever the context children is reset, since the
|
|
58
|
+
# cached default logger is now invalid
|
|
59
|
+
def reset_children_default_logger
|
|
60
|
+
children = log_children
|
|
61
|
+
@log_children = Array.new
|
|
62
|
+
children.each do |ref|
|
|
63
|
+
begin
|
|
64
|
+
ref.__getobj__.reset_default_logger
|
|
65
|
+
rescue WeakRef::RefError
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
|
|
44
70
|
# Allows to change the logger object at this level of the hierarchy
|
|
45
71
|
#
|
|
46
72
|
# This is usually not used directly: a new logger can be created with
|
|
47
73
|
# Hierarchy#make_own_logger and removed with Hierarchy#reset_own_logger
|
|
48
74
|
def logger=(new_logger)
|
|
49
75
|
@logger = new_logger
|
|
50
|
-
|
|
51
|
-
child.reset_default_logger
|
|
52
|
-
end
|
|
76
|
+
reset_children_default_logger
|
|
53
77
|
end
|
|
54
78
|
|
|
55
79
|
# Removes a logger defined at this level of the module hierarchy. The
|
|
56
80
|
# logging methods will now access the parent's module logger.
|
|
57
81
|
def reset_own_logger
|
|
58
|
-
|
|
59
|
-
each_log_child do |child|
|
|
60
|
-
child.reset_default_logger
|
|
61
|
-
end
|
|
82
|
+
self.logger = nil
|
|
62
83
|
end
|
|
63
84
|
|
|
64
85
|
def reset_default_logger
|
|
65
86
|
@__utilrb_hierarchy__default_logger = nil
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
end
|
|
87
|
+
@parent_module.deregister_log_child(self) if @parent_module
|
|
88
|
+
reset_children_default_logger
|
|
69
89
|
end
|
|
70
90
|
|
|
71
91
|
def logger
|
|
72
92
|
if defined?(@logger) && @logger
|
|
73
|
-
return @logger
|
|
93
|
+
return @logger
|
|
74
94
|
elsif defined?(@__utilrb_hierarchy__default_logger) && @__utilrb_hierarchy__default_logger
|
|
75
95
|
return @__utilrb_hierarchy__default_logger
|
|
76
96
|
end
|
|
@@ -84,7 +104,7 @@ class Logger
|
|
|
84
104
|
# attribute.
|
|
85
105
|
#
|
|
86
106
|
# This module is usually used in conjunction with the Logger::Root method:
|
|
87
|
-
#
|
|
107
|
+
#
|
|
88
108
|
# module First
|
|
89
109
|
# extend Logger.Root("First", :INFO)
|
|
90
110
|
#
|
|
@@ -120,7 +140,7 @@ class Logger
|
|
|
120
140
|
def self.extended(obj) # :nodoc:
|
|
121
141
|
obj.logger # initialize the default logger. Also does some checking
|
|
122
142
|
if obj.kind_of?(Module) && !obj.spacename.empty?
|
|
123
|
-
parent_module =
|
|
143
|
+
parent_module = const_get(obj.spacename)
|
|
124
144
|
if (parent_module.singleton_class.ancestors.include?(::Logger::Forward))
|
|
125
145
|
obj.send(:extend, ::Logger::Forward)
|
|
126
146
|
end
|
|
@@ -141,7 +161,7 @@ class Logger
|
|
|
141
161
|
if m.name && !m.spacename.empty?
|
|
142
162
|
parent_module =
|
|
143
163
|
begin
|
|
144
|
-
|
|
164
|
+
const_get(m.spacename)
|
|
145
165
|
rescue NameError
|
|
146
166
|
end
|
|
147
167
|
if parent_module.respond_to?(:logger)
|
|
@@ -164,6 +184,7 @@ class Logger
|
|
|
164
184
|
raise NoParentLogger, "cannot find a logger for #{self}"
|
|
165
185
|
end
|
|
166
186
|
if parent_module.respond_to? :register_log_child
|
|
187
|
+
@parent_module = parent_module
|
|
167
188
|
parent_module.register_log_child(self)
|
|
168
189
|
end
|
|
169
190
|
parent_module.logger
|
|
@@ -173,5 +194,3 @@ class Logger
|
|
|
173
194
|
end
|
|
174
195
|
end
|
|
175
196
|
end
|
|
176
|
-
|
|
177
|
-
|
|
@@ -1,10 +1,13 @@
|
|
|
1
|
-
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
class Module # rubocop:disable Style/Documentation
|
|
2
4
|
# call-seq:
|
|
3
5
|
# dsl_attribute(name)
|
|
4
6
|
# dsl_attribute(name,name2,name3)
|
|
5
7
|
# dsl_attribute(name) { |value| ... }
|
|
6
8
|
#
|
|
7
|
-
# This defines a +name+ instance method on the given class which accepts
|
|
9
|
+
# This defines a +name+ instance method on the given class which accepts
|
|
10
|
+
# zero or one argument
|
|
8
11
|
#
|
|
9
12
|
# Without any argument, it acts as a getter for the +@name+ attribute. With
|
|
10
13
|
# one argument, it acts instead as a setter for the same attribute and
|
|
@@ -13,8 +16,8 @@ class Module
|
|
|
13
16
|
# instance variable. This block can therefore both filter the value
|
|
14
17
|
# (convert it to a desired form) and validate it.
|
|
15
18
|
#
|
|
16
|
-
# The goal of this method is to have a nicer way to handle attribute in
|
|
17
|
-
# of
|
|
19
|
+
# The goal of this method is to have a nicer way to handle attribute in
|
|
20
|
+
# DSLs: instead of
|
|
18
21
|
#
|
|
19
22
|
# model = create_model do
|
|
20
23
|
# self.my_model_attribute = 'bla'
|
|
@@ -35,37 +38,46 @@ class Module
|
|
|
35
38
|
# end
|
|
36
39
|
#
|
|
37
40
|
def dsl_attribute(*names, &filter_block)
|
|
38
|
-
if names.size > 1
|
|
39
|
-
|
|
41
|
+
if names.size > 1
|
|
42
|
+
if filter_block
|
|
43
|
+
raise ArgumentError,
|
|
44
|
+
"multiple names as argument are only supported if no block is given"
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
names.each { |name| dsl_attribute(name) }
|
|
48
|
+
return
|
|
40
49
|
end
|
|
41
|
-
|
|
42
|
-
|
|
50
|
+
|
|
51
|
+
name = names.first
|
|
52
|
+
|
|
53
|
+
class_eval do
|
|
43
54
|
if filter_block
|
|
44
55
|
define_method("__dsl_attribute__#{name}__filter__", &filter_block)
|
|
45
56
|
end
|
|
46
57
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
58
|
+
define_method(name) do |*value, **kw|
|
|
59
|
+
if value.empty? && kw.empty?
|
|
60
|
+
instance_variable_get("@#{name}")
|
|
61
|
+
elsif filter_block
|
|
62
|
+
# Ruby 2.7 madness. The second version would pass {} as
|
|
63
|
+
# second argument
|
|
64
|
+
filtered_value =
|
|
65
|
+
if kw.empty?
|
|
66
|
+
send("__dsl_attribute__#{name}__filter__", *value)
|
|
67
|
+
else
|
|
68
|
+
send("__dsl_attribute__#{name}__filter__", *value, **kw)
|
|
69
|
+
end
|
|
70
|
+
instance_variable_set("@#{name}", filtered_value)
|
|
71
|
+
self
|
|
72
|
+
else
|
|
59
73
|
if value.size == 1
|
|
60
74
|
instance_variable_set("@#{name}", value.first)
|
|
61
75
|
else
|
|
62
76
|
instance_variable_set("@#{name}", value)
|
|
63
77
|
end
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
end
|
|
78
|
+
self
|
|
79
|
+
end
|
|
80
|
+
end
|
|
68
81
|
end
|
|
69
82
|
end
|
|
70
83
|
end
|
|
71
|
-
|
|
@@ -1,8 +1,20 @@
|
|
|
1
1
|
|
|
2
2
|
class Object
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
3
|
+
if RUBY_VERSION < "2.7.0"
|
|
4
|
+
# Return the object address (for non immediate
|
|
5
|
+
# objects).
|
|
6
|
+
def address
|
|
7
|
+
Object.address_from_id(object_id)
|
|
8
|
+
end
|
|
9
|
+
else
|
|
10
|
+
BUILTIN_OBJECT_TO_S = Object.instance_method(:to_s)
|
|
11
|
+
def address
|
|
12
|
+
to_s = BUILTIN_OBJECT_TO_S.bind(self).call
|
|
13
|
+
if (m = /:(0x[0-9a-f]+)/.match(to_s))
|
|
14
|
+
Integer(m[1])
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
6
18
|
|
|
7
19
|
# Converts the object_id of a non-immediate object
|
|
8
20
|
# to its memory address
|
|
@@ -27,6 +27,8 @@ class Object
|
|
|
27
27
|
class_eval <<-EOD, __FILE__, __LINE__+1
|
|
28
28
|
def #{name}
|
|
29
29
|
if instance_variable_defined?(:@#{name}) then @#{name}
|
|
30
|
+
elsif frozen?
|
|
31
|
+
#{name}_defval
|
|
30
32
|
else @#{name} = #{name}_defval
|
|
31
33
|
end
|
|
32
34
|
end
|
|
@@ -40,4 +42,3 @@ class Object
|
|
|
40
42
|
singleton_class.class_eval { attribute(attr_def, &init) }
|
|
41
43
|
end
|
|
42
44
|
end
|
|
43
|
-
|