From 7de5f2968091c6ad25b877f3472a6cdf95fc09d7 Mon Sep 17 00:00:00 2001
From: Jack Turnbull <git@jack.codes>
Date: Mon, 2 Sep 2019 18:01:58 +0900
Subject: [PATCH] (session) compose session hash

Currently seeing a compiler bug when attempting to compile with raven.cr. Although I'm not convinced entirely that this is an issue with action-controller, it does seem to be considered good practice to stick with composition rather than inheritence for this sort of stuff (https://github.com/crystal-lang/crystal/issues/3238#issuecomment-244548787).

The approach taken was effectively the same as amberframework/amber#930 which fixed the same issue within Amber.
---
 src/action-controller/session.cr | 19 +++++++++++--------
 1 file changed, 11 insertions(+), 8 deletions(-)

diff --git a/src/action-controller/session.cr b/src/action-controller/session.cr
index 24c0227..928009d 100644
--- a/src/action-controller/session.cr
+++ b/src/action-controller/session.cr
@@ -3,7 +3,7 @@ require "random"
 require "./session/message_verifier"
 require "./session/message_encryptor"
 
-class ActionController::Session < Hash(String, String | Int64 | Float64 | Bool)
+class ActionController::Session
   NEVER = 622_080_000 # (~20 years in seconds)
   # Cookies can typically store 4096 bytes.
   MAX_COOKIE_SIZE = 4096
@@ -22,10 +22,11 @@ class ActionController::Session < Hash(String, String | Int64 | Float64 | Bool)
   getter modified : Bool
   property domain : String?
   @encoder : MessageEncryptor | MessageVerifier
+  @store : Hash(String, String | Int64 | Float64 | Bool)
 
-  def initialize
-    super
+  forward_missing_to @store
 
+  def initialize
     @modified = false
     @existing = false
     @domain = settings.domain
@@ -35,6 +36,8 @@ class ActionController::Session < Hash(String, String | Int64 | Float64 | Bool)
     else
       @encoder = MessageVerifier.new(settings.secret)
     end
+
+    @store = {} of String => String | Int64 | Float64 | Bool
   end
 
   def self.from_cookies(cookies)
@@ -82,7 +85,7 @@ class ActionController::Session < Hash(String, String | Int64 | Float64 | Bool)
     if value.nil?
       delete(key)
     else
-      super(key, value)
+      @store[key] = value
       @modified = true
     end
     value
@@ -90,22 +93,22 @@ class ActionController::Session < Hash(String, String | Int64 | Float64 | Bool)
 
   def clear
     @modified = true if @existing
-    super
+    @store.clear
   end
 
   def delete(key)
     @modified = true
-    super(key)
+    @store.delete(key)
   end
 
   def delete(key, &block)
     @modified = true
-    super(key, &block)
+    @store.delete(key, &block)
   end
 
   def delete_if(&block)
     @modified = true
-    super(&block)
+    @store.delete_if(&block)
   end
 
   def touch