Sha256: 60ea9f37d7e1cdc0b956614624933915524d35d4448b82fe24b949de8ba33692

Contents?: true

Size: 1.57 KB

Versions: 1

Compression:

Stored size: 1.57 KB

Contents

# frozen_string_literal: true

# ClassAttributes.define klass, :layout, 'default_value_optional'
# klass.layout -> get value
# klass.layout = value -> set value

# class A
#   ClassAttributes.define self, :layout, 'default'
# end
# class B < A
#   layout 'l B'
# end
# class C < B
# end
# puts A.layout # default
# puts B.layout # l B
# puts C.layout # l B

# class User
#   ClassAttributes.define_in_current_thread self, :current
# end

# User.current = User.first

module ClassAttributes
  extend self

  CA_DEFAULTS = {}

  # defines class variable
  def define klass, name, default=nil, &block
    raise ArgumentError, 'name must be symbol' unless name.class == Symbol

    default ||= block if block

    ::ClassAttributes::CA_DEFAULTS[name] = { 'Object'=>default }

    klass.class.send(:define_method, name) do |*args|
      root = ::ClassAttributes::CA_DEFAULTS[name]

      # set and return if argument defined
      return root[self.to_s] = args[0] if args.length > 0

      # find value and return
      self.ancestors.map(&:to_s).each do |el|
        value = root[el]
        if value || el == 'Object'
          value = self.instance_exec(&value) if value.is_a?(Proc)
          return value
        end
      end
    end
  end

  # defines class variable in current lux thread
  def current klass, name
    klass.class.send(:define_method, name) do |*args|
      Thread.current[:lux]['%s-%s' % [klass, name]]
    end

    klass.class.send(:define_method, '%s=' % name) do |value|
      Thread.current[:lux] ||= {}
      Thread.current[:lux]['%s-%s' % [klass, name]] = value
    end
  end
end

Version data entries

1 entries across 1 versions & 1 rubygems

Version Path
lux-fw-0.1.17 ./lib/common/class_attributes.rb