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
|
# File 'lib/functionable.rb', line 7
def self.extended descendant
descendant.singleton_class.class_eval do
def extended(*) = fail NoMethodError, "Module extend is disabled."
def included(*) = fail NoMethodError, "Module include is disabled."
def prepended(*) = fail NoMethodError, "Module prepend is disabled."
def module_function(*) = fail NoMethodError, "Module function behavior is disabled."
def public(*) = fail NoMethodError, "Public visibility is disabled."
def protected(*) = fail NoMethodError, "Protected visibility is disabled."
def private(*) = fail NoMethodError, "Private visibility is disabled, use conceal instead."
def conceal(*) = private_class_method(*)
def alias_method to, from
fail NoMethodError, "Aliasing #{from.inspect} as #{to.inspect} is disabled."
end
def class_variable_set(name, ...)
fail NoMethodError, "Setting class variable #{name.inspect} is disabled."
end
def class_variable_get name
fail NoMethodError, "Getting class variable #{name.inspect} is disabled."
end
def const_set(name, ...) = fail NoMethodError, "Setting constant #{name.inspect} is disabled."
def define_method(name, ...)
fail NoMethodError, "Defining method #{name.inspect} is disabled."
end
def remove_method name
return super if instance_variable_get :@functionable
fail NoMethodError, "Removing method #{name.inspect} is disabled."
end
def undef_method(name) = fail NoMethodError, "Undefining method #{name.inspect} is disabled."
def singleton_method_added name, allowed: i[method_added singleton_method_added].freeze
return super(name) if allowed.include?(name) || instance_variable_get(:@functionable)
fail NoMethodError,
"Avoid defining #{name.inspect} as a class method because the method will be " \
"automatically converted to a class method for you."
end
def method_added name
unbound = instance_method name
instance_variable_set :@functionable, true
remove_method name
define_singleton_method name, unbound
instance_variable_set :@functionable, false
super
ensure
instance_variable_set :@functionable, false
end
end
end
|