Module: ProxyMethod::ClassMethods
- Defined in:
- lib/proxy_method.rb
Constant Summary collapse
- DEFAULT_PROXY_MESSAGE =
'Disabled by proxy_method'- DEFAULT_PREFIX =
'unproxied_'
Instance Method Summary collapse
-
#proxied ⇒ Object
Return a proxied version of this class.
-
#proxy_class_method(*original_method_names, &proxy_block) ⇒ Object
Proxy one or more inherited class methods, so that they are not used directly.
-
#proxy_instance_method(*original_method_names, &proxy_block) ⇒ Object
(also: #proxy_method)
Proxy one or more inherited instance methods, so that they are not used directly.
-
#unproxied ⇒ Object
Return an unproxied version of this class.
Instance Method Details
#proxied ⇒ Object
Return a proxied version of this class.
If the class has previously been “unproxied”, this returns a copy where all proxies are re-enabled.
243 244 245 |
# File 'lib/proxy_method.rb', line 243 def proxied self.dup.send(:reproxy!) end |
#proxy_class_method(*original_method_names, &proxy_block) ⇒ Object
Proxy one or more inherited class methods, so that they are not used directly. Given this base class:
class Animal
def self.create
'created'
end
def destroy
'destroyed'
end
end
The simplest implementation is to pass just a single method name:
class Dog < Animal
proxy_class_method :create
end
Dog.create
# => RuntimeError: Disabled by proxy_method
Dog.destroy
# => 'destroyed'
Or multiple method names:
class Dog < Animal
proxy_class_method :create, :destroy
end
Dog.create
# => RuntimeError: Disabled by proxy_method
Dog.destroy
# => RuntimeError: Disabled by proxy_method
With a custom error message:
class Dog < Animal
proxy_class_method :create, raise: 'Disabled!'
end
Dog.create
# => RuntimeError: Disabled!
You can still access the unproxied version by prefixing ‘unproxied_’ to the method name:
Dog.unproxied_create
# => 'created'
And you can change the prefix for unproxied versions:
class Dog < Animal
proxy_class_method :create, prefix: 'original_'
end
Dog.original_create
# => 'created'
Finally, you can actually proxy the method, by providing an alternative block of code to run:
class Dog < Animal
proxy_class_method(:create) do |object, method_name, *args, &block|
"indirectly #{object.send(method_name)}"
end
end
Dog.create
# => 'indirectly created'
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 |
# File 'lib/proxy_method.rb', line 80 def proxy_class_method(*original_method_names, &proxy_block) = if original_method_names.last.is_a?(Hash) original_method_names.pop else {} end original_method_names = Array(original_method_names).flatten = [:raise] || DEFAULT_PROXY_MESSAGE prefix = [:prefix] || DEFAULT_PREFIX original_method_names.each do |original_method_name| proxied_class_methods.merge!(original_method_name => prefix) new_method_name = :"#{prefix}#{original_method_name}" self.singleton_class.send(:alias_method, new_method_name, original_method_name) define_singleton_method(original_method_name) do |*args, &block| if proxy_class_methods_enabled? if proxy_block proxy_block.call(self.unproxied, original_method_name, *args, &block) else raise end else send(new_method_name, *args, &block) end end end end |
#proxy_instance_method(*original_method_names, &proxy_block) ⇒ Object Also known as: proxy_method
Proxy one or more inherited instance methods, so that they are not used directly. Given this base class:
class Animal
def save
'saved'
end
def update
'updated'
end
end
The simplest implementation is to pass just a single method name:
class Dog < Animal
proxy_instance_method :save
end
Dog.new.save
# => RuntimeError: Disabled by proxy_method
Dog.new.upate
# => 'updated'
Or use the shorthand form:
class Dog < Animal
proxy_method :save
end
Or multiple method names:
class Dog < Animal
proxy_method :save, :update
end
Dog.new.save
# => RuntimeError: Disabled by proxy_method
Dog.new.update
# => RuntimeError: Disabled by proxy_method
With a custom error message:
class Dog < Animal
proxy_method :save, raise: 'Disabled!'
end
Dog.new.save
# => RuntimeError: Disabled!
You can still access the unproxied version by prefixing ‘unproxied_’ to the method name:
Dog.new.unproxied_save
# => 'saved'
And you can change the prefix for unproxied versions:
class Dog < Animal
proxy_method :save, prefix: 'original_'
end
Dog.new.original_save
# => 'saved'
Finally, you can actually proxy the method, by providing an alternative block of code to run:
class Dog < Animal
proxy_method(:save) do |object, method_name, *args, &block|
"indirectly #{object.send(method_name)}"
end
end
Dog.new.save
# => 'indirectly saved'
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 |
# File 'lib/proxy_method.rb', line 192 def proxy_instance_method(*original_method_names, &proxy_block) = if original_method_names.last.is_a?(Hash) original_method_names.pop else {} end original_method_names = Array(original_method_names).flatten = [:raise] || DEFAULT_PROXY_MESSAGE prefix = [:prefix] || DEFAULT_PREFIX original_method_names.each do |original_method_name| proxied_instance_methods.merge!(original_method_name => prefix) new_method_name = :"#{prefix}#{original_method_name}" alias_method new_method_name, original_method_name define_method(original_method_name) do |*args, &block| if proxy_instance_methods_enabled? if proxy_block proxy_block.call(self.unproxied, original_method_name, *args, &block) else raise end else send(new_method_name, *args, &block) end end end end |
#unproxied ⇒ Object
Return an unproxied version of this class.
This returns a copy of the class where all proxies are disabled. This is sometimes necessary when a proxied method is being called by a different method outside your control.
233 234 235 |
# File 'lib/proxy_method.rb', line 233 def unproxied self.dup.send(:unproxy!) end |