Functional flags: practice inside or outside the method?

We use function flags to enable / disable some functions in our system.

I had a discussion with my colleague about the standard way to add function flags to the code itself:

Consider the following method:

def featured_method do_this do_that end 

The method is called from about 15 different places inside our code.

You would recommend adding a check to see if the function is enabled before each call to this method:

 if feature_enabled?(:feature_key) featured_method end 

Or inside the featured_method element itself, for example:

 def featured_method if feature_enabled?(:feature_key) do_this do_that end end 

The advantage of having a condition inside the method itself is obvious: the DRY code and the fact that when you want to constantly add a function, you simply remove the condition from the method.

The advantage of having a condition over each call is that it is very clear whether this method is executed or not without going into the featured_method code itself, which can save a lot of headaches.

I was wondering if there is another solution or standard for such problems.

+4
source share
2 answers

I would combine both approaches.

This will result in dry codes on the caller side. It will not violate SRP in feature_method , and it will clearly communicate what happens - if you can find a better name than me:

 def may_execute_featured_method featured_method if feature_enabled?(:feature_key) end def featured_method do_this do_that end 

Caller uses may_execute_featured_method

+3
source

I will be tempted to split the keying function into my own module and use it as follows:

 class Foo include FeatureKeyed def foo 'foo' end feature_keyed :foo def bar 'bar' end feature_keyed :bar end foo = Foo.new p foo.foo # => "foo" p foo.bar # => FeatureKeyed::FeatureDisabled 

Here's the module:

 module FeatureKeyed class FeatureDisabled < StandardError ; end def self.included(base) base.extend ClassMethods end module ClassMethods def feature_keyed(method_name, feature_key = method_name) orig_method = instance_method(method_name) define_method method_name do |*args| raise FeatureDisabled unless feature_enabled?(feature_key) orig_method.bind(self).call *args end end end def feature_enabled?(feature_key) feature_key == :foo end end 

Notes:

  • feature_enabled? hardcodes eneabled function names. You would change that.
  • This code throws an exception if the function is disabled. The code in your question just returns. Do what makes sense for your application. If you need different "not included" behavior for different methods, then the behavior can be passed to the feature_keyed function.
  • the _feature_keyed_ method will take a second argument, which is the function key. If absent, the method name is used as the function key.
+1
source

Source: https://habr.com/ru/post/1480682/


All Articles