-
-
Notifications
You must be signed in to change notification settings - Fork 3k
/
top_level_method_definition.rb
85 lines (75 loc) · 1.97 KB
/
top_level_method_definition.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
# frozen_string_literal: true
module RuboCop
module Cop
module Style
# Newcomers to ruby applications may write top-level methods,
# when ideally they should be organized in appropriate classes or modules.
# This cop looks for definitions of top-level methods and warns about them.
#
# However for ruby scripts it is perfectly fine to use top-level methods.
# Hence this cop is disabled by default.
#
# @example
# # bad
# def some_method
# end
#
# # bad
# def self.some_method
# end
#
# # bad
# define_method(:foo) { puts 1 }
#
# # good
# module Foo
# def some_method
# end
# end
#
# # good
# class Foo
# def self.some_method
# end
# end
#
# # good
# Struct.new do
# def some_method
# end
# end
#
# # good
# class Foo
# define_method(:foo) { puts 1 }
# end
class TopLevelMethodDefinition < Base
MSG = 'Do not define methods at the top-level.'
RESTRICT_ON_SEND = %i[define_method].freeze
def on_def(node)
return unless top_level_method_definition?(node)
add_offense(node)
end
alias on_defs on_def
alias on_send on_def
def on_block(node)
return unless define_method_block?(node) && top_level_method_definition?(node)
add_offense(node)
end
alias on_numblock on_block
private
def top_level_method_definition?(node)
if node.parent&.begin_type?
node.parent.root?
else
node.root?
end
end
# @!method define_method_block?(node)
def_node_matcher :define_method_block?, <<~PATTERN
({block numblock} (send _ :define_method _) ...)
PATTERN
end
end
end
end