Sha256: 0c585a8fc3274474cfbd4f77b4f2180702fa7f8368175e10042e9850b0e2f2b1

Contents?: true

Size: 1.79 KB

Versions: 1

Compression:

Stored size: 1.79 KB

Contents

require 'set'
module Surrounded
  module Context
    def self.extended(base)
      base.send(:include, InstanceMethods)
    end

    def triggers
      @triggers.dup
    end

    private

    def setup(*setup_args)
      attr_reader(*setup_args)
      private(*setup_args)

      define_method(:initialize){ |*args|
        Hash[setup_args.zip(args)].each{ |role, object|

          role_module_name = Context.classify_string(role)
          klass = self.class

          if mod = klass.const_defined?(role_module_name) && !mod.is_a?(Class)
            object = Context.modify(object, klass.const_get(role_module_name))
          end

          roles[role.to_s] = object
          instance_variable_set("@#{role}", object)
        }
      }
    end

    def trigger(name, *args, &block)
      store_trigger(name)

      define_method(:"trigger_#{name}", *args, &block)

      private :"trigger_#{name}"

      define_method(name, *args){
        begin
          (Thread.current[:context] ||= []).unshift(self)
          self.send("trigger_#{name}", *args)
        ensure
          (Thread.current[:context] ||= []).shift
        end
      }
    end

    def store_trigger(name)
      @triggers ||= Set.new
      @triggers << name
    end

    def self.classify_string(string)
      string.to_s.gsub(/(?:^|_)([a-z])/) { $1.upcase }
    end

    def self.modify(obj, mod)
      return obj if mod.is_a?(Class)
      if obj.respond_to?(:cast_as)
        obj.cast_as(mod)
      else
        obj.extend(mod)
      end
    end

    module InstanceMethods
      def role?(name, &block)
        accessor = eval('self', block.binding)
        roles.values.include?(accessor) && roles[name.to_s]
      end

      def triggers
        self.class.triggers
      end

      private

      def roles
        @roles ||= {}
      end
    end
  end
end

Version data entries

1 entries across 1 versions & 1 rubygems

Version Path
surrounded-0.1.0 lib/surrounded/context.rb