darthjee/core_ext

View on GitHub
lib/darthjee/core_ext/class.rb

Summary

Maintainability
A
0 mins
Test Coverage
# frozen_string_literal: true

module Darthjee
  module CoreExt
    # @api public
    module Class
      private

      # @!visibility public
      # Adds a method that will return a default value
      #
      # the value is evaluated on class definition, meaning that
      # everytime it is called it will be the same instance
      #
      # @param [::Symbol,::String] name Name of the method to be added
      # @param [::Object] value default value
      #
      # @example Defining a default value
      #   class MyClass
      #     default_value :name, 'John'
      #   end
      #
      #   MyClass.new.name # returns 'John'
      #
      # @example Comparing value across instances
      #   class MyClass
      #     default_value :name, 'John'
      #   end
      #
      #   instance = MyClass.new
      #   other = MyClass.new
      #
      #   instance.name.equal?('John')      # returns false
      #   instance.name.equal?(other.name)  # returns true
      #
      # @return [::Symbol] The name of the added method
      def default_value(name, value)
        define_method(name) { |*_| value }
      end

      # @!visibility public
      # Adds methods that will return a default value
      #
      # the value is evaluated on class definition, meaning that
      # everytime any of them are called they will return the same instance
      # of value
      #
      # @param [::Array<::Symbol,::String>] names Names of the
      #   methods to be added
      # @param [::Object] value default value
      #
      # @see default_value
      #
      # @example Defining a default values
      #   class MyClass
      #     default_values :name, :nick_name, 'John'
      #   end
      #
      #   MyClass.new.name      # returns 'John'
      #   MyClass.new.nick_name # returns 'John'
      #
      # @example Comparing value across instances
      #   class MyClass
      #     default_values :name, :nick_name, 'John'
      #   end
      #
      #   instance = MyClass.new
      #   other = MyClass.new
      #
      #   instance.name.equal?('John')     # returns false
      #   instance.name.equal?(other.name) # returns true
      #
      # @example Comparing value across methods
      #   class MyClass
      #     default_values :name, :nick_name, 'John'
      #   end
      #
      #   instance = MyClass.new
      #
      #   instance.nick_name.equal?('John')        # returns false
      #   instance.nick_name.equal?(instance.name) # returns true
      #
      # @return [::Array<::Symbol>] Name of defined methods
      def default_values(*names, value)
        names.map do |name|
          default_value(name, value)
        end
      end

      # @!visibility public
      #
      # Creates a method that will act as reader with default value
      #
      # The method will be a reader, but when no value was
      # defined for the instance variable, it will
      # return a default
      #
      # @param [::Symbol,::String] name Name of the method to be added
      # @param [::Object] value default value
      #
      # @example Defining a default value
      #   class Person
      #     attr_writer :name
      #     default_reader :name, 'John Doe'
      #   end
      #
      #   model = Person.new
      #
      #   model.name # returns 'John Doe'
      #
      # @example Changing the instance value
      #
      #   model = Person.new
      #   model.name # returns 'John Doe'
      #
      #   model.name = 'Joe'
      #   model.name # returns 'Joe'
      #
      #   model.name = nil
      #   model.name # returns nil
      #
      # @example Changing values accros instances
      #
      #   model = Person.new
      #   model.name # returns 'John Doe'
      #
      #   model.name = 'Bob'
      #   model.name # returns 'Bob'
      #   Person.new.name # returns 'John Doe'
      #
      # @return [::Symbol] Defined method name
      def default_reader(name, value)
        define_method(name) do
          return value unless instance_variable_defined?("@#{name}")
          instance_variable_get("@#{name}")
        end
      end

      # @!visibility public
      #
      # Creates methods that will act as reader with default value
      #
      # The methods will be readers, but when no value was
      # defined for the instance variable, it will
      # return a default
      #
      # @param [::Array<::Symbol,::String>] names Names of the
      #   methods to be added
      # @param [::Object] value default value
      #
      # @example Defining default values
      #   class Person
      #     attr_writer :cars, :houses
      #     default_reader :cars, :houses, 'none'
      #   end
      #
      #   model = Person.new
      #
      #   model.cars # returns 'none'
      #
      # @example Changing the instance value
      #
      #   model = Person.new
      #   model.cars # returns 'none'
      #
      #   model.cars = ['volvo']
      #   model.cars # returns ['volvo']
      #
      #   model.cars = nil
      #   model.cars # returns nil
      #
      # @example Changing values accros instances
      #
      #   model = Person.new
      #   model.cars # returns 'none'
      #
      #   model.cars = ['volvo']
      #   model.cars # returns ['volvo']
      #   Person.new.cars # returns 'none'
      #
      # @example Comparing value across methods
      #   model.cars                           # returns 'none'
      #   model.cars.equal?('none')            # returns false
      #   model.nick_name.equal?(model.houses) # returns true
      #
      # @return [::Array<::Symbol>] Name of defined methods
      def default_readers(*names, value)
        names.map do |name|
          default_reader(name, value)
        end
      end
    end
  end
end

class Class
  include Darthjee::CoreExt::Class
end