nrser 0.3.4 → 0.3.5

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: c22fc11ecea67d2e92ae41a8cf469a7f33d9cf88
4
- data.tar.gz: bed78e5268a47d2e8e64c1f124e6fedb8e8ca900
3
+ metadata.gz: e9a0b7b61d0a481af1ca35a8eb86e7ab13aff165
4
+ data.tar.gz: e7c16292a7f5ccfa34ce0e490a7f91313f9e34e5
5
5
  SHA512:
6
- metadata.gz: 678f023739443e98fca66a347a4ce7e3077b0245ad75dfce625a2a53aa44e93cac9d65ddaf2662c93117427da054ebe53b6812d1ca9dc91182fbed41a80cda80
7
- data.tar.gz: 47f21b60c61f23e5eff76c627d805ce62f60a9be852f02d0eee8fa95fb7c912f1581632d099408a2b9f8cff361829a301224537b2514fa641bcbc345b3d72117
6
+ metadata.gz: e085701c29d0a89e2983734e8a2d120fe1d03248cf2d8bf5644761f1e00c5fd8d20bcf676a09785b312cb85c81cd1203330d5011ffcf956916f95dae3cdec16f
7
+ data.tar.gz: 68bd8090335751c9ee51f2026c33d23acecdb4faad507b89879fe036fb3758f79a3ba934682a26a6613601ce36b129bd3048ee62613b8751e0089f0d32cf4b58
@@ -0,0 +1,21 @@
1
+ require_relative '../module/names'
2
+
3
+
4
+ class Method
5
+
6
+ # Returns the method's {#receiver} and {#name} in the common
7
+ # `A.cls_meth` / `A#inst_meth` format.
8
+ #
9
+ def full_name
10
+ case receiver
11
+ when Module
12
+ "#{ receiver.safe_name }.#{ name }"
13
+ else
14
+ "#{ receiver.class.safe_name }##{ name }"
15
+ end
16
+ end
17
+
18
+ # Use full name as a {Method}'s "summary"
19
+ alias_method :to_summary, :full_name
20
+
21
+ end # class Method
@@ -0,0 +1 @@
1
+ require_relative './method/full_name'
@@ -101,7 +101,8 @@ class Module
101
101
  def own_instance_method_locations sort: true,
102
102
  include_initialize: false,
103
103
  only_valid: false
104
- instance_method_locations sort: sort,
104
+ instance_method_locations false,
105
+ sort: sort,
105
106
  include_initialize: include_initialize,
106
107
  only_valid: only_valid
107
108
  end
@@ -0,0 +1,16 @@
1
+ require_relative '../module/names'
2
+
3
+
4
+ class UnboundMethod
5
+
6
+ # Instance Methods
7
+ # ========================================================================
8
+
9
+ def full_name
10
+ # Need to string parse {#to_s}?!
11
+ raise NotImplementedError, "Haven't done this one yet"
12
+ end
13
+
14
+ alias_method :to_summary, :full_name
15
+
16
+ end # class Method
@@ -160,6 +160,8 @@ module NRSER::NicerError
160
160
  # The formatted string for the segment.
161
161
  #
162
162
  def format_message_segment segment
163
+ return segment.to_summary if segment.respond_to?( :to_summary )
164
+
163
165
  return segment if String === segment
164
166
 
165
167
  # TODO Do better!
@@ -64,6 +64,41 @@ class NRSER::Log::Logger < SemanticLogger::Logger
64
64
  end # class Catcher
65
65
 
66
66
 
67
+ class Notifier
68
+
69
+ # Construction
70
+ # ========================================================================
71
+
72
+ # Instantiate a new `Notifier`.
73
+ #
74
+ # @param [NRSER::Log::Logger] logger
75
+ # The logger to use if the block raises.
76
+ #
77
+ # @param [*] on_fail:
78
+ # Value to return when `&block` raises.
79
+ #
80
+ def initialize logger
81
+ @logger = logger
82
+ end # #initialize
83
+
84
+
85
+ # Instance Methods
86
+ # ========================================================================
87
+
88
+ SemanticLogger::LEVELS.each do |level|
89
+ define_method level do |message = nil, payload = nil, &block|
90
+ begin
91
+ block.call
92
+ rescue Exception => error
93
+ @logger.send level, message, payload, error
94
+ @on_fail
95
+ end
96
+ end
97
+ end
98
+
99
+ end
100
+
101
+
67
102
  # Attributes
68
103
  # ========================================================================
69
104
 
@@ -0,0 +1,94 @@
1
+ # encoding: UTF-8
2
+ # frozen_string_literal: true
3
+
4
+ # Requirements
5
+ # =======================================================================
6
+
7
+ # Stdlib
8
+ # -----------------------------------------------------------------------
9
+
10
+ # Deps
11
+ # -----------------------------------------------------------------------
12
+
13
+ # Project / Package
14
+ # -----------------------------------------------------------------------
15
+
16
+ # Need {NRSER::LazyAttr} decorator.
17
+ require 'nrser/meta/lazy_attr'
18
+
19
+
20
+ # Namespace
21
+ # =======================================================================
22
+
23
+ module NRSER
24
+ module Log
25
+
26
+
27
+ # Definitions
28
+ # =======================================================================
29
+
30
+ # Abstraction to attempt to notify interactive users.
31
+ #
32
+ module Notify
33
+
34
+ +NRSER::LazyAttr
35
+ # Is the `terminal-notifier` gem available?
36
+ #
37
+ # [terminal-notifier][] is not an NRSER dependency since it does not make
38
+ # sense for many systems and situations. It must be installed separately.
39
+ #
40
+ # [terminal-notifier]: https://rubygems.org/gems/terminal-notifier
41
+ #
42
+ # Tests by trying to `require` it.
43
+ #
44
+ # @return [Boolean]
45
+ #
46
+ def self.terminal_notifier?
47
+ begin
48
+ require 'terminal-notifier'
49
+ rescue LoadError => error
50
+ false
51
+ else
52
+ true
53
+ end
54
+ end # .terminal_notifier?
55
+
56
+
57
+ +NRSER::LazyAttr
58
+ # Can we send notification to the user?
59
+ #
60
+ # Right now, only {.terminal_notifier?} is tested, but we can add more
61
+ # options in the future.
62
+ #
63
+ # @return [Boolean]
64
+ #
65
+ def self.available?
66
+ terminal_notifier?
67
+ end # .available?
68
+
69
+
70
+ # Send a notification to the use *if* notifications are {.available?}.
71
+ #
72
+ #
73
+ def self.notify *args, &block
74
+ return false unless available?
75
+
76
+ notify! *args, &block
77
+ end
78
+
79
+
80
+ def self.notify! *args, &block
81
+ require 'terminal-notifier'
82
+
83
+ TerminalNotifier.notify *args, &block
84
+ end
85
+
86
+
87
+ end # module Notify
88
+
89
+
90
+ # /Namespace
91
+ # =======================================================================
92
+
93
+ end # module Log
94
+ end # module NRSER
@@ -0,0 +1,114 @@
1
+ # encoding: UTF-8
2
+ # frozen_string_literal: true
3
+
4
+ # Requirements
5
+ # =======================================================================
6
+
7
+ # Deps
8
+ # -----------------------------------------------------------------------
9
+
10
+ require 'method_decorators'
11
+
12
+
13
+ # Namespace
14
+ # =======================================================================
15
+
16
+ module NRSER
17
+
18
+
19
+ # Definitions
20
+ # =======================================================================
21
+
22
+ # Store the result of an attribute method (no args) in an instance variable
23
+ # of the same name and return that value on subsequent calls.
24
+ #
25
+ class LazyAttr < MethodDecorators::Decorator
26
+
27
+ # Get the instance variable name for a target method.
28
+ #
29
+ # @param [Method] target_method
30
+ # The method the decorator is decorating.
31
+ #
32
+ # @return [String]
33
+ # The name of the instance variable, ready to be provided to
34
+ # `#instance_variable_set` (has `@` prefix).
35
+ #
36
+ def self.instance_var_name target_method
37
+ name = target_method.name.to_s
38
+
39
+ # Allow predicate methods by chopping off the `?` character.
40
+ #
41
+ # Other stupid uses like `+` or whatever will raise when
42
+ # `#instance_variable_set` is called.
43
+ #
44
+ name = name[0..-2] if name.end_with? '?'
45
+
46
+ "@#{ name }"
47
+ end # .instance_var_name
48
+
49
+
50
+ # Execute the decorator.
51
+ #
52
+ # @param [Method] target_method
53
+ # The decorated method, already bound to the receiver.
54
+ #
55
+ # The `method_decorators` gem calls this `orig`, but I thought
56
+ # `target_method` made more sense.
57
+ #
58
+ # @param [*] receiver
59
+ # The object that will receive the call to `target`.
60
+ #
61
+ # The `method_decorators` gem calls this `this`, but I thought `receiver`
62
+ # made more sense.
63
+ #
64
+ # It's just `target.receiver`, but the API is how it is.
65
+ #
66
+ # @param [Array] *args
67
+ # Any arguments the decorated method was called with.
68
+ #
69
+ # @param [Proc?] &block
70
+ # The block the decorated method was called with (if any).
71
+ #
72
+ # @return
73
+ # Whatever `target_method` returns.
74
+ #
75
+ def call target_method, receiver, *args, &block
76
+ unless target_method.parameters.empty?
77
+ raise NRSER::ArgumentError.new \
78
+ "{NRSER::LazyAttr} can only decorate methods with 0 params",
79
+ receiver: receiver,
80
+ target_method: target_method
81
+ end
82
+
83
+ unless args.empty?
84
+ raise NRSER::ArgumentError.new \
85
+ "wrong number of arguments for", target_method,
86
+ "(given", args.length, "expected 0)",
87
+ receiver: receiver,
88
+ target_method: target_method
89
+ end
90
+
91
+ unless block.nil?
92
+ raise NRSER::ArgumentError.new \
93
+ "wrong number of arguments (given #{ args.length }, expected 0)",
94
+ receiver: receiver,
95
+ target_method: target_method
96
+ end
97
+
98
+ var_name = self.class.instance_var_name target_method
99
+
100
+ unless receiver.instance_variable_defined? var_name
101
+ receiver.instance_variable_set var_name, target_method.call
102
+ end
103
+
104
+ receiver.instance_variable_get var_name
105
+
106
+ end # #call
107
+
108
+ end # class LazyAttr
109
+
110
+
111
+ # /Namespace
112
+ # =======================================================================
113
+
114
+ end # module NRSER
@@ -78,7 +78,27 @@ class NRSER::Meta::Source::Location < Hamster::Vector
78
78
  # Props
79
79
  # ======================================================================
80
80
 
81
+ # @!attribute [r] file
82
+ # The first entry in the source location array, denoting the file path.
83
+ #
84
+ # @return [String]
85
+ # Source file absolute path.
86
+ #
87
+ # @return [nil]
88
+ # No source file available.
89
+ #
81
90
  prop :file, type: t.abs_path?, default: nil, index: 0
91
+
92
+
93
+ # @!attribute [r] line
94
+ # The second entry in the source location array, denoting the line number.
95
+ #
96
+ # @return [Integer]
97
+ # Positive integer line number in the source {#file}.
98
+ #
99
+ # @return [nil]
100
+ # No line number available.
101
+ #
82
102
  prop :line, type: t.pos_int?, default: nil, index: 1
83
103
 
84
104
 
data/lib/nrser/version.rb CHANGED
@@ -18,7 +18,7 @@ module NRSER
18
18
  #
19
19
  # @return [String]
20
20
  #
21
- VERSION = '0.3.4'
21
+ VERSION = '0.3.5'
22
22
 
23
23
 
24
24
  module Version
@@ -0,0 +1,41 @@
1
+ require 'nrser/core_ext/method/full_name'
2
+
3
+ describe_spec_file(
4
+ spec_path: __FILE__,
5
+ class: ::Method,
6
+ instance_method: :full_name,
7
+ ) do
8
+
9
+ describe_setup %{
10
+ get `method_name` from `receiver` and call `#full_name` on it
11
+ }.squish do
12
+ subject do
13
+ receiver.method( method_name ).full_name
14
+ end
15
+
16
+ describe_case %{ class methods for } do
17
+
18
+ describe_when receiver: Object, method_name: :new do
19
+ it { is_expected.to eq "Object.new" }
20
+ end
21
+
22
+ describe_when receiver: NRSER, method_name: :rest do
23
+ it { is_expected.to eq "NRSER.rest" }
24
+ end
25
+
26
+ end # class methods
27
+
28
+
29
+ describe_case "instance methods" do
30
+ describe_when receiver: Object.new, method_name: :to_s do
31
+ it %{ Returns the receiver's class,
32
+ even if method is not defined there }.squish do
33
+ is_expected.to eq "Object#to_s"
34
+ end
35
+ end
36
+
37
+ end # instance methods
38
+
39
+ end # setup
40
+
41
+ end # Spec File Description
@@ -0,0 +1,115 @@
1
+ require 'nrser/meta/lazy_attr'
2
+
3
+ describe_spec_file(
4
+ spec_path: __FILE__,
5
+ class: NRSER::LazyAttr,
6
+ ) do
7
+
8
+ describe_setup %{ Decorate a class instance method } do
9
+ my_class = Class.new do
10
+ extend ::MethodDecorators
11
+
12
+ def self.name
13
+ 'MyClass'
14
+ end
15
+
16
+ attr_reader :count
17
+
18
+ def initialize
19
+ @count = 0
20
+ end
21
+
22
+ +NRSER::LazyAttr
23
+ def f
24
+ @count += 1
25
+ 'eff!'
26
+ end
27
+
28
+ end
29
+
30
+ instance = my_class.new
31
+
32
+ it %{ starts out with call count 0 } do
33
+ expect( instance.count ).to be 0
34
+ end
35
+
36
+ it %{ returns the correct result when called } do
37
+ expect( instance.f ).to eq 'eff!'
38
+ end
39
+
40
+ it %{ now has the instance variable set } do
41
+ expect( instance.instance_variable_get :@f ).to eq 'eff!'
42
+ end
43
+
44
+ it %{ now has call count 1 } do
45
+ expect( instance.count ).to be 1
46
+ end
47
+
48
+ it %{ returns the same result when called again } do
49
+ expect( instance.f ).to eq "eff!"
50
+ end
51
+
52
+ it %{ still has call count 1 } do
53
+ expect( instance.count ).to be 1
54
+ end
55
+
56
+ it %{ still has the instance var set to the result } do
57
+ expect( instance.instance_variable_get :@f ).to eq 'eff!'
58
+ end
59
+
60
+ end # instance method
61
+
62
+
63
+ describe_setup %{ Decorate a class method } do
64
+ my_class = Class.new do
65
+ extend ::MethodDecorators
66
+
67
+ def self.name
68
+ 'MyClass'
69
+ end
70
+
71
+ @count = 0
72
+
73
+ def self.count
74
+ @count
75
+ end
76
+
77
+ +NRSER::LazyAttr
78
+ def self.f
79
+ @count += 1
80
+ 'eff!'
81
+ end
82
+
83
+ end
84
+
85
+ it %{ starts out with call count 0 } do
86
+ expect( my_class.count ).to be 0
87
+ end
88
+
89
+ it %{ returns the correct result when called } do
90
+ expect( my_class.f ).to eq 'eff!'
91
+ end
92
+
93
+ it %{ now has the instance variable set } do
94
+ expect( my_class.instance_variable_get :@f ).to eq 'eff!'
95
+ end
96
+
97
+ it %{ now has call count 1 } do
98
+ expect( my_class.count ).to be 1
99
+ end
100
+
101
+ it %{ returns the same result when called again } do
102
+ expect( my_class.f ).to eq "eff!"
103
+ end
104
+
105
+ it %{ still has call count 1 } do
106
+ expect( my_class.count ).to be 1
107
+ end
108
+
109
+ it %{ still has the instance var set to the result } do
110
+ expect( my_class.instance_variable_get :@f ).to eq 'eff!'
111
+ end
112
+
113
+ end # class method
114
+
115
+ end # Spec File Description
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: nrser
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.4
4
+ version: 0.3.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - nrser
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-05-24 00:00:00.000000000 Z
11
+ date: 2018-05-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: hamster
@@ -94,6 +94,20 @@ dependencies:
94
94
  - - "~>"
95
95
  - !ruby/object:Gem::Version
96
96
  version: '5.1'
97
+ - !ruby/object:Gem::Dependency
98
+ name: method_decorators
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - "~>"
102
+ - !ruby/object:Gem::Version
103
+ version: 0.9.6
104
+ type: :runtime
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - "~>"
109
+ - !ruby/object:Gem::Version
110
+ version: 0.9.6
97
111
  - !ruby/object:Gem::Dependency
98
112
  name: bundler
99
113
  requirement: !ruby/object:Gem::Requirement
@@ -242,6 +256,8 @@ files:
242
256
  - lib/nrser/core_ext/hash/bury.rb
243
257
  - lib/nrser/core_ext/hash/extract_values_at.rb
244
258
  - lib/nrser/core_ext/hash/transform_values_with_keys.rb
259
+ - lib/nrser/core_ext/method.rb
260
+ - lib/nrser/core_ext/method/full_name.rb
245
261
  - lib/nrser/core_ext/module.rb
246
262
  - lib/nrser/core_ext/module/method_objects.rb
247
263
  - lib/nrser/core_ext/module/names.rb
@@ -253,6 +269,7 @@ files:
253
269
  - lib/nrser/core_ext/string.rb
254
270
  - lib/nrser/core_ext/symbol.rb
255
271
  - lib/nrser/core_ext/time.rb
272
+ - lib/nrser/core_ext/unbound_method/full_name.rb
256
273
  - lib/nrser/errors.rb
257
274
  - lib/nrser/errors/abstract_method_error.rb
258
275
  - lib/nrser/errors/argument_error.rb
@@ -314,11 +331,13 @@ files:
314
331
  - lib/nrser/log/formatters/mixin.rb
315
332
  - lib/nrser/log/logger.rb
316
333
  - lib/nrser/log/mixin.rb
334
+ - lib/nrser/log/notify.rb
317
335
  - lib/nrser/mean_streak.rb
318
336
  - lib/nrser/mean_streak/document.rb
319
337
  - lib/nrser/message.rb
320
338
  - lib/nrser/meta.rb
321
339
  - lib/nrser/meta/class_attrs.rb
340
+ - lib/nrser/meta/lazy_attr.rb
322
341
  - lib/nrser/meta/source/location.rb
323
342
  - lib/nrser/no_arg.rb
324
343
  - lib/nrser/props.rb
@@ -403,6 +422,7 @@ files:
403
422
  - spec/lib/nrser/core_ext/enumerable/find_map_spec.rb
404
423
  - spec/lib/nrser/core_ext/hash/short_transform_keys_spec.rb
405
424
  - spec/lib/nrser/core_ext/hash_spec.rb
425
+ - spec/lib/nrser/core_ext/method/full_name_spec.rb
406
426
  - spec/lib/nrser/errors/abstract_method_error_spec.rb
407
427
  - spec/lib/nrser/functions/enumerable/associate_spec.rb
408
428
  - spec/lib/nrser/functions/enumerable/find_all_map_spec.rb
@@ -433,6 +453,7 @@ files:
433
453
  - spec/lib/nrser/mean_streak/design_spec.rb
434
454
  - spec/lib/nrser/mean_streak/identity_instance_spec.rb
435
455
  - spec/lib/nrser/meta/class_attrs_spec.rb
456
+ - spec/lib/nrser/meta/lazy_attr_spec.rb
436
457
  - spec/lib/nrser/meta/source/location_spec.rb
437
458
  - spec/lib/nrser/op/message_spec.rb
438
459
  - spec/lib/nrser/props/immutable/hash_spec.rb
@@ -493,6 +514,7 @@ test_files:
493
514
  - spec/lib/nrser/core_ext/enumerable/find_map_spec.rb
494
515
  - spec/lib/nrser/core_ext/hash/short_transform_keys_spec.rb
495
516
  - spec/lib/nrser/core_ext/hash_spec.rb
517
+ - spec/lib/nrser/core_ext/method/full_name_spec.rb
496
518
  - spec/lib/nrser/errors/abstract_method_error_spec.rb
497
519
  - spec/lib/nrser/functions/enumerable/associate_spec.rb
498
520
  - spec/lib/nrser/functions/enumerable/find_all_map_spec.rb
@@ -523,6 +545,7 @@ test_files:
523
545
  - spec/lib/nrser/mean_streak/design_spec.rb
524
546
  - spec/lib/nrser/mean_streak/identity_instance_spec.rb
525
547
  - spec/lib/nrser/meta/class_attrs_spec.rb
548
+ - spec/lib/nrser/meta/lazy_attr_spec.rb
526
549
  - spec/lib/nrser/meta/source/location_spec.rb
527
550
  - spec/lib/nrser/op/message_spec.rb
528
551
  - spec/lib/nrser/props/immutable/hash_spec.rb