module ReeActions::DSL::ClassMethods

def action(name, &proc)

def action(name, &proc)
  dsl = Ree::ObjectDsl.new(
    Ree.container.packages_facade, name, self, :fn
  )
  dsl.instance_exec(&proc) if block_given?
  dsl.tags(["action"])
  dsl.freeze(false)
  dsl.object.set_as_compiled(false)
  Ree.container.compile(dsl.package, name)
end

def method_added(method_name)

def method_added(method_name)
  return super if method_name != :call
  if @__original_call_defined
    remove_instance_variable(:@__original_call_defined)
    return
  end
  @__original_call_defined = true
  alias_method(:__original_call, :call)
  define_method :call do |user_access, attrs, &proc|
    if self.class.const_defined?(:ActionCaster)
      caster = self.class.const_get(:ActionCaster)
      if !caster.respond_to?(:cast)
        raise ArgumentError.new("ActionCaster does not respond to `cast` method")
      end
      attrs = begin
        caster.cast(attrs)
      rescue ReeMapper::TypeError, ReeMapper::CoercionError => e
        raise ReeActions::ParamError, e.message
      end
    end
    __original_call(user_access, attrs, &proc)
  end
  nil
end