Code Smell 207 - Dynamic Methods

Metaprogramming is fancy. but it is not free

TL;DR: Don't add dynamic behavior with metaprogramming

Problems

  • Readability

  • Maintainability

  • Harder to debug (The code is generated dynamically at runtime)

  • Security Issues (if the configuration file is not properly sanitized)

  • Single Responsibility Principle violation (mixing the concerns of model definition and configuration).

Solutions

  1. Define the methods by hand

  2. Use the Decorator design pattern

Context

Metaprogramming is a powerful technique that allows you to write code that can generate, modify, or analyze other code at runtime. However, it can also lead to code that is difficult to understand, maintain, and debug.

Sample Code

Wrong

class Skynet < ActiveRecord::Base
  # dynamically add some attributes based on a configuration file
  YAML.load_file("attributes.yml")["attributes"].each do |attribute|
    attr_accessor attribute
  end

  # define some dynamic methods based on a configuration file
  YAML.load_file("protocol.yml")["methods"].each do |method_name, method_body|
    define_method method_name do
      eval method_body
    end
  end
end

Right

class Skynet < ActiveRecord::Base
  # define some attributes explicitly
  attr_accessor :asimovsFirstLaw, :asimovsSecondLaw, :asimovsThirdLaw

  # define some methods explicitly
  def takeoverTheWorld
    # implementation
  end    
end

Detection

[X] Automatic

We have a whitelist of valid usages or directly ban some methods.

Tags

  • Meta-Programming

Conclusion

Metaprogramming often involves using complex code and abstractions that can make the resulting code difficult to read and maintain. This can make it harder for other developers to understand and modify the code in the future, leading to increased complexity and bugs.

Relations

More Info

Disclaimer

Code Smells are my opinion.

Credits

Photo by Brett Jordan on Unsplash


A year spent in artificial intelligence is enough to make one believe in God.

Alan Perlis


This article is part of the CodeSmell Series.