hanami-utils 1.3.7 → 2.0.0.alpha1

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.
@@ -103,25 +103,25 @@ module Hanami
103
103
 
104
104
  # @since 0.8.0
105
105
  # @api private
106
- def _message_hash(message)
106
+ def _message_hash(message) # rubocop:disable Metrics/MethodLength
107
107
  case message
108
- when Hash
108
+ when ::Hash
109
109
  @filter.call(message)
110
110
  when Exception
111
- Hash[
112
- message: message.message,
111
+ ::Hash[
112
+ message: message.message,
113
113
  backtrace: message.backtrace || [],
114
- error: message.class
114
+ error: message.class
115
115
  ]
116
116
  else
117
- Hash[message: message]
117
+ ::Hash[message: message]
118
118
  end
119
119
  end
120
120
 
121
121
  # @since 0.8.0
122
122
  # @api private
123
123
  def _format(hash)
124
- "#{_line_front_matter(hash.delete(:app), hash.delete(:severity), hash.delete(:time))}#{SEPARATOR}#{_format_message(hash)}" # rubocop:disable Layout/LineLength
124
+ "#{_line_front_matter(hash.delete(:app), hash.delete(:severity), hash.delete(:time))}#{SEPARATOR}#{_format_message(hash)}"
125
125
  end
126
126
 
127
127
  # @since 1.2.0
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Hanami
4
+ module Middleware
5
+ # Hanami middleware utils
6
+
7
+ # @since 2.0.0
8
+ class Error < ::StandardError
9
+ end
10
+ end
11
+ end
@@ -23,7 +23,7 @@ module Hanami
23
23
 
24
24
  # Checks if the current VM is JRuby
25
25
  #
26
- # @return [TrueClass,FalseClass] info whether the VM is JRuby or not
26
+ # @return [TrueClass,FalseClass] return if the VM is JRuby or not
27
27
  #
28
28
  # @since 0.3.1
29
29
  # @api private
@@ -33,7 +33,7 @@ module Hanami
33
33
 
34
34
  # Checks if the current VM is Rubinius
35
35
  #
36
- # @return [TrueClass,FalseClass] info whether the VM is Rubinius or not
36
+ # @return [TrueClass,FalseClass] return if the VM is Rubinius or not
37
37
  #
38
38
  # @since 0.3.1
39
39
  # @api private
@@ -41,7 +41,7 @@ module Hanami
41
41
  RUBY_ENGINE == HANAMI_RUBINIUS
42
42
  end
43
43
 
44
- # Recursively requires Ruby files under the given directory.
44
+ # Recursively require Ruby files under the given directory.
45
45
  #
46
46
  # If the directory is relative, it implies it's the path from current directory.
47
47
  # If the directory is absolute, it uses as it is.
@@ -56,22 +56,6 @@ module Hanami
56
56
  for_each_file_in(directory) { |file| require_relative(file) }
57
57
  end
58
58
 
59
- # Recursively reloads Ruby files under the given directory.
60
- #
61
- # If the directory is relative, it implies it's the path from current directory.
62
- # If the directory is absolute, it uses as it is.
63
- #
64
- # It respects file separator of the current operating system.
65
- # A pattern like <tt>"path/to/files"</tt> will work both on *NIX and Windows machines.
66
- #
67
- # @param directory [String, Pathname] the directory
68
- #
69
- # @since 1.0.0
70
- # @api private
71
- def self.reload!(directory)
72
- for_each_file_in(directory) { |file| load(file) }
73
- end
74
-
75
59
  # Recursively scans through the given directory and yields the given block
76
60
  # for each Ruby source file.
77
61
  #
@@ -6,24 +6,7 @@ module Hanami
6
6
  #
7
7
  # @since 0.3.5
8
8
  class BasicObject < ::BasicObject
9
- # Lookups constants at the top-level namespace, if they are missing in the
10
- # current context.
11
- #
12
- # @param name [Symbol] the constant name
13
- #
14
- # @return [Object, Module] the constant
15
- #
16
- # @raise [NameError] if the constant cannot be found
17
- #
18
- # @since 1.3.4
19
- # @api private
20
- #
21
- # @see https://ruby-doc.org/core/Module.html#method-i-const_missing
22
- def self.const_missing(name)
23
- ::Object.const_get(name)
24
- end
25
-
26
- # Returns the class for debugging purposes.
9
+ # Return the class for debugging purposes.
27
10
  #
28
11
  # @since 0.3.5
29
12
  #
@@ -40,56 +23,13 @@ module Hanami
40
23
  #
41
24
  # @see http://ruby-doc.org/core/Object.html#method-i-inspect
42
25
  #
26
+ # rubocop:disable Style/FormatString
43
27
  # rubocop:disable Style/FormatStringToken
44
28
  def inspect
45
29
  "#<#{self.class}:#{'0x0000%x' % (__id__ << 1)}#{__inspect}>"
46
30
  end
47
31
  # rubocop:enable Style/FormatStringToken
48
-
49
- # @!macro [attach] instance_of?(class)
50
- #
51
- # Determines if self is an instance of given class or module
52
- #
53
- # @param class [Class,Module] the class of module to verify
54
- #
55
- # @return [TrueClass,FalseClass] the result of the check
56
- #
57
- # @raise [TypeError] if the given argument is not of the expected types
58
- #
59
- # @since 1.3.2
60
- #
61
- # @see http://ruby-doc.org/core/Object.html#method-i-instance_of-3F
62
- define_method :instance_of?, ::Object.instance_method(:instance_of?)
63
-
64
- # @!macro [attach] is_a?(class)
65
- #
66
- # Determines if self is of the type of the object class or module
67
- #
68
- # @param class [Class,Module] the class of module to verify
69
- #
70
- # @return [TrueClass,FalseClass] the result of the check
71
- #
72
- # @raise [TypeError] if the given argument is not of the expected types
73
- #
74
- # @since 1.3.2
75
- #
76
- # @see http://ruby-doc.org/core/Object.html#method-i-is_a-3F
77
- define_method :is_a?, ::Object.instance_method(:is_a?)
78
-
79
- # @!macro [attach] kind_of?(class)
80
- #
81
- # Determines if self is of the kind of the object class or module
82
- #
83
- # @param class [Class,Module] the class of module to verify
84
- #
85
- # @return [TrueClass,FalseClass] the result of the check
86
- #
87
- # @raise [TypeError] if the given argument is not of the expected types
88
- #
89
- # @since 1.3.2
90
- #
91
- # @see http://ruby-doc.org/core/Object.html#method-i-kind_of-3F
92
- define_method :kind_of?, ::Object.instance_method(:kind_of?)
32
+ # rubocop:enable Style/FormatString
93
33
 
94
34
  # Alias for __id__
95
35
  #
@@ -13,7 +13,7 @@ module Hanami
13
13
  # @api private
14
14
  STRING_MATCHER = /\A[[:space:]]*\z/.freeze
15
15
 
16
- # Checks if object is blank
16
+ # Checks object is blank
17
17
  #
18
18
  # @example Basic Usage
19
19
  # require 'hanami/utils/blank'
@@ -21,21 +21,20 @@ module Hanami
21
21
  # Hanami::Utils::Blank.blank?(Hanami::Utils::String.new('')) # => true
22
22
  # Hanami::Utils::Blank.blank?(' ') # => true
23
23
  # Hanami::Utils::Blank.blank?(nil) # => true
24
- # Hanami::Utils::Blank.blank?(Hanami::Utils::Hash.new({})) # => true
25
24
  # Hanami::Utils::Blank.blank?(true) # => false
26
25
  # Hanami::Utils::Blank.blank?(1) # => false
27
26
  #
28
27
  # @param object the argument
29
28
  #
30
- # @return [TrueClass,FalseClass] info, whether object is blank
29
+ # @return [TrueClass,FalseClass]
31
30
  #
32
31
  # @since 0.8.0
33
32
  # @api private
34
- def self.blank?(object)
33
+ def self.blank?(object) # rubocop:disable Metrics/MethodLength
35
34
  case object
36
35
  when String, ::String
37
36
  STRING_MATCHER === object # rubocop:disable Style/CaseEquality
38
- when Hash, ::Hash, ::Array
37
+ when ::Hash, ::Array
39
38
  object.empty?
40
39
  when TrueClass, Numeric
41
40
  false
@@ -46,7 +45,7 @@ module Hanami
46
45
  end
47
46
  end
48
47
 
49
- # Checks if object is filled
48
+ # Checks object is filled
50
49
  #
51
50
  # @example Basic Usage
52
51
  # require 'hanami/utils/blank'
@@ -56,11 +55,10 @@ module Hanami
56
55
  # Hanami::Utils::Blank.filled?(Hanami::Utils::String.new('')) # => false
57
56
  # Hanami::Utils::Blank.filled?(' ') # => false
58
57
  # Hanami::Utils::Blank.filled?(nil) # => false
59
- # Hanami::Utils::Blank.filled?(Hanami::Utils::Hash.new({})) # => false
60
58
  #
61
59
  # @param object the argument
62
60
  #
63
- # @return [TrueClass,FalseClass] whether the object is filled
61
+ # @return [TrueClass,FalseClass]
64
62
  #
65
63
  # @since 1.0.0
66
64
  # @api private
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "concurrent/array"
4
+
3
5
  module Hanami
4
6
  module Utils
5
7
  # Before and After callbacks
@@ -12,13 +14,13 @@ module Hanami
12
14
  # @since 0.1.0
13
15
  # @private
14
16
  class Chain
15
- # Returns a new chain
17
+ # Return a new chain
16
18
  #
17
19
  # @return [Hanami::Utils::Callbacks::Chain]
18
20
  #
19
21
  # @since 0.2.0
20
22
  def initialize
21
- @chain = []
23
+ @chain = Concurrent::Array.new
22
24
  end
23
25
 
24
26
  # Appends the given callbacks to the end of the chain.
@@ -150,6 +152,17 @@ module Hanami
150
152
  end
151
153
  end
152
154
 
155
+ # Return a duplicate callbacks chain
156
+ #
157
+ # @return [Hanami::Utils::Callbacks] the duplicated chain
158
+ #
159
+ # @since 2.0.0
160
+ def dup
161
+ super.tap do |instance|
162
+ instance.instance_variable_set(:@chain, instance.chain.dup)
163
+ end
164
+ end
165
+
153
166
  # It freezes the object by preventing further modifications.
154
167
  #
155
168
  # @since 0.2.0
@@ -170,6 +183,10 @@ module Hanami
170
183
  @chain.freeze
171
184
  end
172
185
 
186
+ protected
187
+
188
+ attr_reader :chain
189
+
173
190
  private
174
191
 
175
192
  # @api private
@@ -250,9 +267,7 @@ module Hanami
250
267
  end
251
268
 
252
269
  # Method callback
253
- #
254
- # It wraps a symbol or a string representing a method name that is
255
- # implemented by the context within it will be called.
270
+ # It wraps a symbol or a string representing a method name that is implemented by the context within it will be called.
256
271
  #
257
272
  # @since 0.1.0
258
273
  # @api private
@@ -74,59 +74,9 @@ module Hanami
74
74
  load!(name, namespace) if namespace.const_defined?(name.to_s, false)
75
75
  end
76
76
 
77
- # Loads a class from the given pattern name and namespace
78
- #
79
- # @param pattern [String] the class name pattern
80
- # @param namespace [Class, Module] the Ruby namespace where we want to perform the lookup.
81
- # @return [Class, Module] the found Ruby constant.
82
- #
83
- # @raise [NameError] if no constant can be found.
84
- #
85
- # @since 0.3.1
86
- #
87
- # @see Hanami::Utils::String#tokenize
88
- #
89
- # @example
90
- # require 'hanami/utils/class'
91
- #
92
- # module App
93
- # module Service
94
- # class Endpoint
95
- # end
96
- # end
97
- #
98
- # class ServiceEndpoint
99
- # end
100
- # end
101
- #
102
- # # basic usage
103
- # Hanami::Utils::Class.load_from_pattern!('App::Service') # => App::Service
104
- #
105
- # # with explicit namespace
106
- # Hanami::Utils::Class.load_from_pattern!('Service', App) # => App::Service
107
- #
108
- # # with pattern
109
- # Hanami::Utils::Class.load_from_pattern!('App::Service(::Endpoint|Endpoint)') # => App::Service::Endpoint
110
- # Hanami::Utils::Class.load_from_pattern!('App::Service(Endpoint|::Endpoint)') # => App::ServiceEndpoint
111
- #
112
- # # with missing constant
113
- # Hanami::Utils::Class.load_from_pattern!('Unknown') # => raises NameError
114
- def self.load_from_pattern!(pattern, namespace = Object)
115
- Deprecation.new("Hanami::Utils::Class.load_from_pattern! is deprecated, please use Hanami::Utils::Class.load! instead") # rubocop:disable Layout/LineLength
116
-
117
- tokenize(pattern) do |token|
118
- begin
119
- return namespace.const_get(token, false)
120
- rescue NameError # rubocop:disable Lint/SuppressedException
121
- end
122
- end
123
-
124
- full_name = [(namespace == Object ? nil : namespace), pattern].compact.join("::")
125
- raise NameError.new("uninitialized constant #{full_name}")
126
- end
127
-
77
+ # rubocop:disable Metrics/MethodLength
128
78
  def self.tokenize(pattern)
129
- if match = TOKENIZE_REGEXP.match(pattern)
79
+ if match = TOKENIZE_REGEXP.match(pattern) # rubocop:disable Lint/AssignmentInCondition
130
80
  pre = match.pre_match
131
81
  post = match.post_match
132
82
  tokens = match[1].split(TOKENIZE_SEPARATOR)
@@ -139,6 +89,7 @@ module Hanami
139
89
 
140
90
  nil
141
91
  end
92
+ # rubocop:enable Metrics/MethodLength
142
93
 
143
94
  # Regexp for .tokenize
144
95
  #
@@ -1,8 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "set"
4
- require "hanami/utils/duplicable"
5
-
6
3
  module Hanami
7
4
  module Utils
8
5
  # Inheritable class level variable accessors.
@@ -10,6 +7,8 @@ module Hanami
10
7
  #
11
8
  # @see Hanami::Utils::ClassAttribute::ClassMethods
12
9
  module ClassAttribute
10
+ require "hanami/utils/class_attribute/attributes"
11
+
13
12
  # @api private
14
13
  def self.included(base)
15
14
  base.extend ClassMethods
@@ -18,6 +17,12 @@ module Hanami
18
17
  # @since 0.1.0
19
18
  # @api private
20
19
  module ClassMethods
20
+ def self.extended(base)
21
+ base.class_eval do
22
+ @__class_attributes = Attributes.new unless defined?(@__class_attributes)
23
+ end
24
+ end
25
+
21
26
  # Defines a class level accessor for the given attribute(s).
22
27
  #
23
28
  # A value set for a superclass is automatically available by their
@@ -68,11 +73,17 @@ module Hanami
68
73
  # SmallAirplane.engines # => 2
69
74
  # SmallAirplane.wheels # => 8
70
75
  def class_attribute(*attributes)
71
- singleton_class.class_eval do
72
- attr_accessor(*attributes)
73
- end
76
+ attributes.each do |attr|
77
+ singleton_class.class_eval %(
78
+ def #{attr}
79
+ class_attributes[:#{attr}]
80
+ end
74
81
 
75
- class_attributes.merge(attributes)
82
+ def #{attr}=(value)
83
+ class_attributes[:#{attr}] = value
84
+ end
85
+ ), __FILE__, __LINE__ - 8
86
+ end
76
87
  end
77
88
 
78
89
  protected
@@ -80,11 +91,9 @@ module Hanami
80
91
  # @see Class#inherited
81
92
  # @api private
82
93
  def inherited(subclass)
83
- class_attributes.each do |attr|
84
- value = send(attr)
85
- value = Duplicable.dup(value)
86
- subclass.class_attribute attr
87
- subclass.send("#{attr}=", value)
94
+ ca = class_attributes.dup
95
+ subclass.class_eval do
96
+ @__class_attributes = ca
88
97
  end
89
98
 
90
99
  super
@@ -95,7 +104,7 @@ module Hanami
95
104
  # Class accessor for class attributes.
96
105
  # @api private
97
106
  def class_attributes
98
- @class_attributes ||= Set.new
107
+ @__class_attributes
99
108
  end
100
109
  end
101
110
  end
@@ -0,0 +1,45 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "concurrent/map"
4
+
5
+ module Hanami
6
+ module Utils
7
+ module ClassAttribute
8
+ # Class attributes set
9
+ #
10
+ # @since 2.0.0
11
+ # @api private
12
+ class Attributes
13
+ # @since 2.0.0
14
+ # @api private
15
+ def initialize(attributes: Concurrent::Map.new)
16
+ @attributes = attributes
17
+ end
18
+
19
+ # @since 2.0.0
20
+ # @api private
21
+ def []=(key, value)
22
+ @attributes[key.to_sym] = value
23
+ end
24
+
25
+ # @since 2.0.0
26
+ # @api private
27
+ def [](key)
28
+ @attributes.fetch(key, nil)
29
+ end
30
+
31
+ # @since 2.0.0
32
+ # @api private
33
+ def dup
34
+ attributes = Concurrent::Map.new.tap do |attrs|
35
+ @attributes.each do |key, value|
36
+ attrs[key.to_sym] = value.dup
37
+ end
38
+ end
39
+
40
+ self.class.new(attributes: attributes)
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end