/
class.rb
125 lines (121 loc) · 3.92 KB
/
class.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
require 'hanami/utils/string'
module Hanami
module Utils
# Class utilities
# @since 0.1.0
class Class
# Loads a class for the given name.
#
# @param name [String, Class] the specific class name
# @param namespace [Class, Module] the Ruby namespace where we want to perform the lookup.
# @return [Class, Module] the found Ruby constant.
#
# @raise [NameError] if no constant can be found.
#
# @since 0.1.0
#
# @example
# require 'hanami/utils/class'
#
# module App
# module Service
# class Endpoint
# end
# end
#
# class ServiceEndpoint
# end
# end
#
# # basic usage
# Hanami::Utils::Class.load!('App::Service') # => App::Service
# Hanami::Utils::Class.load!(App::Service) # => App::Service
#
# # with explicit namespace
# Hanami::Utils::Class.load!('Service', App) # => App::Service
#
# # with missing constant
# Hanami::Utils::Class.load!('Unknown') # => raises NameError
def self.load!(name, namespace = Object)
namespace.const_get(name.to_s, false)
end
# Loads a class for the given name, only if it's defined.
#
# @param name [String, Class] the specific class name
# @param namespace [Class, Module] the Ruby namespace where we want to perform the lookup.
# @return [Class, Module, NilClass] the Ruby constant, or nil if not found.
#
# @since 0.8.0
#
# @example
# require 'hanami/utils/class'
#
# module App
# module Service
# class Endpoint
# end
# end
#
# class ServiceEndpoint
# end
# end
#
# # basic usage
# Hanami::Utils::Class.load('App::Service') # => App::Service
# Hanami::Utils::Class.load(App::Service) # => App::Service
#
# # with explicit namespace
# Hanami::Utils::Class.load('Service', App) # => App::Service
def self.load(name, namespace = Object)
load!(name, namespace) if namespace.const_defined?(name.to_s, false)
end
# Loads a class from the given pattern name and namespace
#
# @param pattern [String] the class name pattern
# @param namespace [Class, Module] the Ruby namespace where we want to perform the lookup.
# @return [Class, Module] the found Ruby constant.
#
# @raise [NameError] if no constant can be found.
#
# @since 0.3.1
#
# @see Hanami::Utils::String#tokenize
#
# @example
# require 'hanami/utils/class'
#
# module App
# module Service
# class Endpoint
# end
# end
#
# class ServiceEndpoint
# end
# end
#
# # basic usage
# Hanami::Utils::Class.load_from_pattern!('App::Service') # => App::Service
#
# # with explicit namespace
# Hanami::Utils::Class.load_from_pattern!('Service', App) # => App::Service
#
# # with pattern
# Hanami::Utils::Class.load_from_pattern!('App::Service(::Endpoint|Endpoint)') # => App::Service::Endpoint
# Hanami::Utils::Class.load_from_pattern!('App::Service(Endpoint|::Endpoint)') # => App::ServiceEndpoint
#
# # with missing constant
# Hanami::Utils::Class.load_from_pattern!('Unknown') # => raises NameError
def self.load_from_pattern!(pattern, namespace = Object)
String.new(pattern).tokenize do |token|
begin
return namespace.const_get(token, false)
rescue NameError # rubocop:disable Lint/HandleExceptions
end
end
full_name = [(namespace == Object ? nil : namespace), pattern].compact.join('::')
raise NameError.new("uninitialized constant #{full_name}")
end
end
end
end