<commit_before># Allows polymorphic behavior based on the value of an attribute by including a module dynamically.
module MoodSwing

  # reader is the value to use as the basis of the included module. The convention for naming the include is:
  # YourClass::YourNameExtension
  #
  # An example would be:
  #
  # class Dog < ActiveRecord::Base
  #   mood_trigger 'breed'
  #
  #   def bark
  #     puts 'woof'
  #   end
  # end
  #
  # module Dog::HoundExtension
  #   def bark
  #     puts 'Hoooooowl'
  #   end
  # end
  #
  # When a instance of dog is initialized the breed attribute is read and it's value is used to extend the current
  # instance's behavior with the module matching following the previously mentioned convention. If the Dog instance's
  # breed was "Hound" then it would be extended with the Dog::HoundExtension. Now when you call @dog.bark, your dog will
  # howl instead of woof.
  #
  # The module is updated when the attribute changes. An example of the behavior to expect with a new object is:
  #
  # spot = Dog.new
  # spot.bark
  # => "woof"
  # spot.breed = "hound"
  # spot.bark
  # => 'Hoooooowl'
  #
  # If your attribute writer is different from the reader, then you can pass in :writer => "your_writer_method" and it
  # will use that. This is the case when using a polymorphic belongs_to accessor as the attribute.
  #
  # belongs_to 'body', :polymorphic => true
  # mood_trigger 'body_type', :writer => 'body'
  #
  # You can pass it an option, :module_format. The default is "%sExtension"
  def mood_trigger(reader, options ={})
    options[:writer] ||= reader
    options[:module_format] ||= "%sExtension"

    define_mood_writer(options[:writer], reader)
    define_mood_loader(options[:module_format], reader)

    class_eval do
      alias_method_chain "#{options[:writer]}=", 'extension'
      after_initialize "#{reader}_extension!"
    end
  end

  def find_module(name)
    self.const_defined?(name) ? self.const_get(name) : self.const_missing(name)
  rescue NameError
  end

  def define_mood_writer(writer, reader)
    define_method("#{writer}_with_extension=") do |value|
      self.send "#{writer}_without_extension=", value
      self.send "#{reader}_extension!"
      self.send reader
    end
  end

  def define_mood_loader(module_format, reader)
    define_method("#{reader}_extension!") do
      return unless kind = self[reader]
      extension_name = module_format % kind.classify
      if extension = self.class.find_module(extension_name)
        self.extend extension
      end
    end
  end
end

ActiveSupport.on_load(:active_record) do
  extend MoodSwing
end<commit_msg>didn't need class_eval. more std default options.<commit_after># Allows polymorphic behavior based on the value of an attribute by including a module dynamically.
module MoodSwing

  # reader is the value to use as the basis of the included module. The convention for naming the include is:
  # YourClass::YourNameExtension
  #
  # An example would be:
  #
  # class Dog < ActiveRecord::Base
  #   mood_trigger 'breed'
  #
  #   def bark
  #     puts 'woof'
  #   end
  # end
  #
  # module Dog::HoundExtension
  #   def bark
  #     puts 'Hoooooowl'
  #   end
  # end
  #
  # When a instance of dog is initialized the breed attribute is read and it's value is used to extend the current
  # instance's behavior with the module matching following the previously mentioned convention. If the Dog instance's
  # breed was "Hound" then it would be extended with the Dog::HoundExtension. Now when you call @dog.bark, your dog will
  # howl instead of woof.
  #
  # The module is updated when the attribute changes. An example of the behavior to expect with a new object is:
  #
  # spot = Dog.new
  # spot.bark
  # => "woof"
  # spot.breed = "hound"
  # spot.bark
  # => 'Hoooooowl'
  #
  # If your attribute writer is different from the reader, then you can pass in :writer => "your_writer_method" and it
  # will use that. This is the case when using a polymorphic belongs_to accessor as the attribute.
  #
  # belongs_to 'body', :polymorphic => true
  # mood_trigger 'body_type', :writer => 'body'
  #
  # You can pass it an option, :module_format. The default is "%sExtension"
  def mood_trigger(reader, _options={})
    options = {
        :writer => reader,
        :module_format => "%sExtension"
    }.update(_options)

    define_mood_writer(options[:writer], reader)
    define_mood_loader(options[:module_format], reader)

    alias_method_chain "#{options[:writer]}=", 'extension'
    after_initialize "#{reader}_extension!"
  end

  def find_module(name)
    self.const_defined?(name) ? self.const_get(name) : self.const_missing(name)
  rescue NameError
  end

  def define_mood_writer(writer, reader)
    define_method("#{writer}_with_extension=") do |value|
      self.send "#{writer}_without_extension=", value
      self.send "#{reader}_extension!"
      self.send reader
    end
  end

  def define_mood_loader(module_format, reader)
    define_method("#{reader}_extension!") do
      return unless kind = self[reader]
      extension_name = module_format % kind.classify
      if extension = self.class.find_module(extension_name)
        self.extend extension
      end
    end
  end
end

ActiveSupport.on_load(:active_record) do
  extend MoodSwing
end
{'fraction_non_alphanumeric': 0.09166352319879291, 'fraction_numerical': 0.0, 'mean_word_length': 3.4940677966101696, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 15, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3051519', 'n_tokens_mistral': 1639, 'n_tokens_neox': 1601, 'n_words': 546}