discorb 0.19.0 → 0.20.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 +4 -4
- data/.github/workflows/build_version.yml +2 -2
- data/.rubocop.yml +12 -75
- data/Changelog.md +10 -0
- data/Rakefile +482 -454
- data/lib/discorb/allowed_mentions.rb +68 -72
- data/lib/discorb/app_command/command.rb +466 -398
- data/lib/discorb/app_command/common.rb +65 -25
- data/lib/discorb/app_command/handler.rb +304 -266
- data/lib/discorb/app_command.rb +5 -5
- data/lib/discorb/application.rb +198 -197
- data/lib/discorb/asset.rb +101 -101
- data/lib/discorb/attachment.rb +134 -119
- data/lib/discorb/audit_logs.rb +412 -385
- data/lib/discorb/automod.rb +279 -269
- data/lib/discorb/channel/base.rb +107 -108
- data/lib/discorb/channel/category.rb +32 -32
- data/lib/discorb/channel/container.rb +44 -44
- data/lib/discorb/channel/dm.rb +26 -28
- data/lib/discorb/channel/guild.rb +311 -246
- data/lib/discorb/channel/stage.rb +156 -140
- data/lib/discorb/channel/text.rb +430 -336
- data/lib/discorb/channel/thread.rb +374 -325
- data/lib/discorb/channel/voice.rb +85 -79
- data/lib/discorb/channel.rb +5 -5
- data/lib/discorb/client.rb +635 -621
- data/lib/discorb/color.rb +178 -182
- data/lib/discorb/common.rb +168 -164
- data/lib/discorb/components/button.rb +107 -106
- data/lib/discorb/components/select_menu.rb +157 -145
- data/lib/discorb/components/text_input.rb +103 -106
- data/lib/discorb/components.rb +68 -66
- data/lib/discorb/dictionary.rb +135 -135
- data/lib/discorb/embed.rb +404 -398
- data/lib/discorb/emoji.rb +309 -302
- data/lib/discorb/emoji_table.rb +16099 -8857
- data/lib/discorb/error.rb +131 -131
- data/lib/discorb/event.rb +360 -314
- data/lib/discorb/event_handler.rb +39 -39
- data/lib/discorb/exe/about.rb +17 -17
- data/lib/discorb/exe/irb.rb +72 -67
- data/lib/discorb/exe/new.rb +323 -315
- data/lib/discorb/exe/run.rb +69 -68
- data/lib/discorb/exe/setup.rb +57 -55
- data/lib/discorb/exe/show.rb +12 -12
- data/lib/discorb/extend.rb +25 -45
- data/lib/discorb/extension.rb +89 -83
- data/lib/discorb/flag.rb +126 -128
- data/lib/discorb/gateway.rb +984 -804
- data/lib/discorb/gateway_events.rb +670 -638
- data/lib/discorb/gateway_requests.rb +45 -48
- data/lib/discorb/guild.rb +2115 -1626
- data/lib/discorb/guild_template.rb +280 -241
- data/lib/discorb/http.rb +247 -232
- data/lib/discorb/image.rb +42 -42
- data/lib/discorb/integration.rb +169 -161
- data/lib/discorb/intents.rb +161 -163
- data/lib/discorb/interaction/autocomplete.rb +76 -62
- data/lib/discorb/interaction/command.rb +279 -224
- data/lib/discorb/interaction/components.rb +114 -104
- data/lib/discorb/interaction/modal.rb +36 -32
- data/lib/discorb/interaction/response.rb +379 -336
- data/lib/discorb/interaction/root.rb +271 -257
- data/lib/discorb/interaction.rb +5 -5
- data/lib/discorb/invite.rb +154 -153
- data/lib/discorb/member.rb +344 -311
- data/lib/discorb/message.rb +615 -544
- data/lib/discorb/message_meta.rb +197 -186
- data/lib/discorb/modules.rb +371 -290
- data/lib/discorb/permission.rb +305 -291
- data/lib/discorb/presence.rb +352 -346
- data/lib/discorb/rate_limit.rb +81 -76
- data/lib/discorb/reaction.rb +55 -54
- data/lib/discorb/role.rb +272 -240
- data/lib/discorb/shard.rb +76 -74
- data/lib/discorb/sticker.rb +193 -171
- data/lib/discorb/user.rb +205 -188
- data/lib/discorb/utils/colored_puts.rb +16 -16
- data/lib/discorb/utils.rb +12 -16
- data/lib/discorb/voice_state.rb +305 -281
- data/lib/discorb/webhook.rb +537 -507
- data/lib/discorb.rb +62 -56
- data/sig/discorb/application.rbs +2 -0
- data/sig/discorb/automod.rbs +10 -1
- data/sig/discorb/guild.rbs +2 -0
- data/sig/discorb/message.rbs +2 -0
- data/sig/discorb/user.rbs +22 -20
- metadata +2 -2
@@ -1,62 +1,76 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Discorb
|
4
|
-
#
|
5
|
-
# Represents auto complete interaction.
|
6
|
-
#
|
7
|
-
class AutoComplete < Interaction
|
8
|
-
@interaction_type = 4
|
9
|
-
@interaction_name = :auto_complete
|
10
|
-
|
11
|
-
private
|
12
|
-
|
13
|
-
def _set_data(data)
|
14
|
-
super
|
15
|
-
Sync do
|
16
|
-
name, options =
|
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
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Discorb
|
4
|
+
#
|
5
|
+
# Represents auto complete interaction.
|
6
|
+
#
|
7
|
+
class AutoComplete < Interaction
|
8
|
+
@interaction_type = 4
|
9
|
+
@interaction_name = :auto_complete
|
10
|
+
|
11
|
+
private
|
12
|
+
|
13
|
+
def _set_data(data)
|
14
|
+
super
|
15
|
+
Sync do
|
16
|
+
name, options =
|
17
|
+
Discorb::CommandInteraction::ChatInputCommand.get_command_data(data)
|
18
|
+
|
19
|
+
unless (
|
20
|
+
command =
|
21
|
+
@client.callable_commands.find do |c|
|
22
|
+
c.to_s == name && c.type_raw == 1
|
23
|
+
end
|
24
|
+
)
|
25
|
+
@client.logger.warn "Unknown command name #{name}, ignoring"
|
26
|
+
next
|
27
|
+
end
|
28
|
+
|
29
|
+
option_map = command.options.to_h { |k, v| [k.to_s, v[:default]] }
|
30
|
+
Discorb::CommandInteraction::ChatInputCommand.modify_option_map(
|
31
|
+
option_map,
|
32
|
+
options,
|
33
|
+
guild,
|
34
|
+
{},
|
35
|
+
{}
|
36
|
+
)
|
37
|
+
focused_index = options.find_index { |o| o[:focused] }
|
38
|
+
val =
|
39
|
+
command.options.values.filter do |option|
|
40
|
+
option[:type] != :attachment
|
41
|
+
end[
|
42
|
+
focused_index
|
43
|
+
][
|
44
|
+
:autocomplete
|
45
|
+
]&.call(self, *command.options.map { |k, _v| option_map[k.to_s] })
|
46
|
+
send_complete_result(val)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def send_complete_result(val)
|
51
|
+
@client
|
52
|
+
.http
|
53
|
+
.request(
|
54
|
+
Route.new(
|
55
|
+
"/interactions/#{@id}/#{@token}/callback",
|
56
|
+
"//interactions/:interaction_id/:token/callback",
|
57
|
+
:post
|
58
|
+
),
|
59
|
+
{
|
60
|
+
type: 8,
|
61
|
+
data: {
|
62
|
+
choices: val.map { |vk, vv| { name: vk, value: vv } }
|
63
|
+
}
|
64
|
+
}
|
65
|
+
)
|
66
|
+
.wait
|
67
|
+
rescue Discorb::NotFoundError
|
68
|
+
@client.logger.warn "Failed to send auto complete result, " \
|
69
|
+
"This may be caused by the suggestion is taking too long (over 3 seconds) to respond"
|
70
|
+
end
|
71
|
+
|
72
|
+
class << self
|
73
|
+
alias make_interaction new
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
@@ -1,224 +1,279 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Discorb
|
4
|
-
#
|
5
|
-
# Represents a command interaction.
|
6
|
-
#
|
7
|
-
class CommandInteraction < Interaction
|
8
|
-
@interaction_type = 2
|
9
|
-
@interaction_name = :application_command
|
10
|
-
include Interaction::SourceResponder
|
11
|
-
include Interaction::ModalResponder
|
12
|
-
|
13
|
-
#
|
14
|
-
# Represents a slash command interaction.
|
15
|
-
#
|
16
|
-
class ChatInputCommand < CommandInteraction
|
17
|
-
@command_type = 1
|
18
|
-
@event_name = :slash_command
|
19
|
-
|
20
|
-
private
|
21
|
-
|
22
|
-
def _set_data(data)
|
23
|
-
super
|
24
|
-
|
25
|
-
name, options = ChatInputCommand.get_command_data(data)
|
26
|
-
|
27
|
-
unless (
|
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
|
-
options
|
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
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
@client.
|
176
|
-
end
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Discorb
|
4
|
+
#
|
5
|
+
# Represents a command interaction.
|
6
|
+
#
|
7
|
+
class CommandInteraction < Interaction
|
8
|
+
@interaction_type = 2
|
9
|
+
@interaction_name = :application_command
|
10
|
+
include Interaction::SourceResponder
|
11
|
+
include Interaction::ModalResponder
|
12
|
+
|
13
|
+
#
|
14
|
+
# Represents a slash command interaction.
|
15
|
+
#
|
16
|
+
class ChatInputCommand < CommandInteraction
|
17
|
+
@command_type = 1
|
18
|
+
@event_name = :slash_command
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
def _set_data(data)
|
23
|
+
super
|
24
|
+
|
25
|
+
name, options = ChatInputCommand.get_command_data(data)
|
26
|
+
|
27
|
+
unless (
|
28
|
+
command =
|
29
|
+
@client.callable_commands.find do |c|
|
30
|
+
c.to_s == name && c.type_raw == 1
|
31
|
+
end
|
32
|
+
)
|
33
|
+
@client.logger.warn "Unknown command name #{name}, ignoring"
|
34
|
+
return
|
35
|
+
end
|
36
|
+
|
37
|
+
option_map = command.options.to_h { |k, v| [k.to_s, v[:default]] }
|
38
|
+
ChatInputCommand.modify_option_map(
|
39
|
+
option_map,
|
40
|
+
options,
|
41
|
+
guild,
|
42
|
+
@members,
|
43
|
+
@attachments
|
44
|
+
)
|
45
|
+
|
46
|
+
command.block.call(
|
47
|
+
self,
|
48
|
+
*command.options.map { |k, _v| option_map[k.to_s] }
|
49
|
+
)
|
50
|
+
end
|
51
|
+
|
52
|
+
class << self
|
53
|
+
#
|
54
|
+
# Get command data from the given data.
|
55
|
+
# @private
|
56
|
+
#
|
57
|
+
# @param [Hash] data The data of the command.
|
58
|
+
#
|
59
|
+
def get_command_data(data)
|
60
|
+
name = data[:name]
|
61
|
+
options = nil
|
62
|
+
return name, options unless (option = data[:options]&.first)
|
63
|
+
|
64
|
+
case option[:type]
|
65
|
+
when 1
|
66
|
+
name += " #{option[:name]}"
|
67
|
+
options = option[:options]
|
68
|
+
when 2
|
69
|
+
name += " #{option[:name]}"
|
70
|
+
unless option[:options]&.first&.[](:type) == 1
|
71
|
+
options = option[:options]
|
72
|
+
return name, options
|
73
|
+
end
|
74
|
+
option_sub = option[:options]&.first
|
75
|
+
name += " #{option_sub[:name]}"
|
76
|
+
options = option_sub[:options]
|
77
|
+
else
|
78
|
+
options = data[:options]
|
79
|
+
end
|
80
|
+
|
81
|
+
[name, options]
|
82
|
+
end
|
83
|
+
|
84
|
+
#
|
85
|
+
# Modify the option map with the given options.
|
86
|
+
# @private
|
87
|
+
#
|
88
|
+
# @param [Hash] option_map The option map to modify.
|
89
|
+
# @param [Array<Hash>] options The options for modifying.
|
90
|
+
# @param [Discorb::Guild] guild The guild where the command is executed.
|
91
|
+
# @param [{Discorb::Snowflake => Discorb::Member}] members The cached members of the guild.
|
92
|
+
# @param [{Integer => Discorb::Attachment}] attachments The cached attachments of the message.
|
93
|
+
def modify_option_map(option_map, options, guild, members, attachments)
|
94
|
+
options ||= []
|
95
|
+
options.each do |option|
|
96
|
+
val =
|
97
|
+
case option[:type]
|
98
|
+
when 3, 4, 5, 10
|
99
|
+
option[:value]
|
100
|
+
when 6
|
101
|
+
members[option[:value]] ||
|
102
|
+
(
|
103
|
+
guild &&
|
104
|
+
(
|
105
|
+
guild.members[option[:value]] ||
|
106
|
+
guild.fetch_member(option[:value]).wait
|
107
|
+
)
|
108
|
+
)
|
109
|
+
when 7
|
110
|
+
if guild
|
111
|
+
guild.channels[option[:value]] ||
|
112
|
+
guild.fetch_channels.wait.find do |channel|
|
113
|
+
channel.id == option[:value]
|
114
|
+
end
|
115
|
+
end
|
116
|
+
when 8
|
117
|
+
guild &&
|
118
|
+
(
|
119
|
+
guild.roles[option[:value]] ||
|
120
|
+
guild.fetch_roles.wait.find do |role|
|
121
|
+
role.id == option[:value]
|
122
|
+
end
|
123
|
+
)
|
124
|
+
when 9
|
125
|
+
members[option[:value]] ||
|
126
|
+
(
|
127
|
+
guild &&
|
128
|
+
(
|
129
|
+
guild.members[option[:value]] ||
|
130
|
+
guild.roles[option[:value]] ||
|
131
|
+
guild.fetch_member(option[:value]).wait ||
|
132
|
+
guild.fetch_roles.wait.find do |role|
|
133
|
+
role.id == option[:value]
|
134
|
+
end
|
135
|
+
)
|
136
|
+
)
|
137
|
+
when 11
|
138
|
+
attachments[option[:value]]
|
139
|
+
end
|
140
|
+
option_map[option[:name]] = val
|
141
|
+
end
|
142
|
+
end
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
#
|
147
|
+
# Represents a user context menu interaction.
|
148
|
+
#
|
149
|
+
class UserMenuCommand < CommandInteraction
|
150
|
+
@command_type = 2
|
151
|
+
@event_name = :user_command
|
152
|
+
|
153
|
+
# @return [Discorb::Member, Discorb::User] The target user.
|
154
|
+
attr_reader :target
|
155
|
+
|
156
|
+
private
|
157
|
+
|
158
|
+
def _set_data(data)
|
159
|
+
super
|
160
|
+
@target =
|
161
|
+
guild.members[data[:target_id]] ||
|
162
|
+
Discorb::Member.new(
|
163
|
+
@client,
|
164
|
+
@guild_id,
|
165
|
+
data[:resolved][:users][data[:target_id].to_sym],
|
166
|
+
data[:resolved][:members][data[:target_id].to_sym]
|
167
|
+
)
|
168
|
+
command =
|
169
|
+
@client.commands.find do |c|
|
170
|
+
c.name["default"] == data[:name] && c.type_raw == 2
|
171
|
+
end
|
172
|
+
if command
|
173
|
+
command.block.call(self, @target)
|
174
|
+
else
|
175
|
+
@client.logger.warn "Unknown command name #{data[:name]}, ignoring"
|
176
|
+
end
|
177
|
+
end
|
178
|
+
end
|
179
|
+
|
180
|
+
#
|
181
|
+
# Represents a message context menu interaction.
|
182
|
+
#
|
183
|
+
class MessageMenuCommand < CommandInteraction
|
184
|
+
@command_type = 3
|
185
|
+
@event_name = :message_command
|
186
|
+
|
187
|
+
# @return [Discorb::Message] The target message.
|
188
|
+
attr_reader :target
|
189
|
+
|
190
|
+
private
|
191
|
+
|
192
|
+
def _set_data(data)
|
193
|
+
super
|
194
|
+
@target = @messages[data[:target_id]]
|
195
|
+
command =
|
196
|
+
@client.commands.find do |c|
|
197
|
+
c.name["default"] == data[:name] && c.type_raw == 3
|
198
|
+
end
|
199
|
+
if command
|
200
|
+
command.block.call(self, @target)
|
201
|
+
else
|
202
|
+
@client.logger.warn "Unknown command name #{data[:name]}, ignoring"
|
203
|
+
end
|
204
|
+
end
|
205
|
+
end
|
206
|
+
|
207
|
+
private
|
208
|
+
|
209
|
+
def _set_data(data)
|
210
|
+
super
|
211
|
+
@name = data[:name]
|
212
|
+
@messages = {}
|
213
|
+
@attachments = {}
|
214
|
+
@members = {}
|
215
|
+
|
216
|
+
if data[:resolved]
|
217
|
+
data[:resolved][:users]&.each do |id, user|
|
218
|
+
@client.users[id] = Discorb::User.new(@client, user)
|
219
|
+
end
|
220
|
+
data[:resolved][:members]&.each do |id, member|
|
221
|
+
@members[id] = Discorb::Member.new(
|
222
|
+
@client,
|
223
|
+
@guild_id,
|
224
|
+
data[:resolved][:users][id],
|
225
|
+
member
|
226
|
+
)
|
227
|
+
end
|
228
|
+
|
229
|
+
data[:resolved][:messages]&.each do |id, message|
|
230
|
+
@messages[id.to_s] = Message.new(
|
231
|
+
@client,
|
232
|
+
message.merge(guild_id: @guild_id.to_s)
|
233
|
+
)
|
234
|
+
end
|
235
|
+
data[:resolved][:attachments]&.each do |id, attachment|
|
236
|
+
@attachments[id.to_s] = Attachment.new(attachment)
|
237
|
+
end
|
238
|
+
end
|
239
|
+
end
|
240
|
+
|
241
|
+
class << self
|
242
|
+
# @private
|
243
|
+
attr_reader :command_type, :event_name
|
244
|
+
|
245
|
+
#
|
246
|
+
# Creates a new CommandInteraction instance for the given data.
|
247
|
+
# @private
|
248
|
+
#
|
249
|
+
# @param [Discorb::Client] client The client.
|
250
|
+
# @param [Hash] data The data for the command.
|
251
|
+
#
|
252
|
+
def make_interaction(client, data)
|
253
|
+
nested_classes.each do |klass|
|
254
|
+
unless !klass.command_type.nil? &&
|
255
|
+
klass.command_type == data[:data][:type]
|
256
|
+
next
|
257
|
+
end
|
258
|
+
interaction = klass.new(client, data)
|
259
|
+
client.dispatch(klass.event_name, interaction)
|
260
|
+
return interaction
|
261
|
+
end
|
262
|
+
client.logger.warn(
|
263
|
+
"Unknown command type #{data[:type]}, initialized CommandInteraction"
|
264
|
+
)
|
265
|
+
CommandInteraction.new(client, data)
|
266
|
+
end
|
267
|
+
|
268
|
+
#
|
269
|
+
# Returns the classes under this class.
|
270
|
+
# @private
|
271
|
+
#
|
272
|
+
def nested_classes
|
273
|
+
constants
|
274
|
+
.select { |c| const_get(c).is_a? Class }
|
275
|
+
.map { |c| const_get(c) }
|
276
|
+
end
|
277
|
+
end
|
278
|
+
end
|
279
|
+
end
|