Skip to content

Commit e5b4d96

Browse files
author
brainopia
committed
Remove SessionHash inheritance from Hash
Previous api provided by SessionHash was inconsistent. All methods provided by Hash which were not rewritten in SessionHash were behaving incorrectly when session was not loaded yet. For example, #replace, #each, #keep_if and many more. So by dropping Hash inheritance we provide clean api with all methods working without regard to whether session was loaded or not.
1 parent 098d583 commit e5b4d96

File tree

1 file changed

+23
-18
lines changed
  • lib/rack/session/abstract

1 file changed

+23
-18
lines changed

lib/rack/session/abstract/id.rb

Lines changed: 23 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -20,20 +20,17 @@ module Abstract
2020

2121
# SessionHash is responsible to lazily load the session from store.
2222

23-
class SessionHash < Hash
23+
class SessionHash
2424
attr_writer :id
2525

2626
def initialize(by, env)
27-
super()
2827
@by = by
2928
@env = env
3029
@loaded = false
31-
@id_loaded = false
3230
end
3331

3432
def id
35-
return @id if @loaded or @id_loaded
36-
@id_loaded = true
33+
return @id if @loaded or instance_variable_defined?(:@id)
3734
@id = @by.send(:extract_session_id, @env)
3835
end
3936

@@ -43,24 +40,26 @@ def options
4340

4441
def [](key)
4542
load_for_read!
46-
super(key.to_s)
43+
@data[key.to_s]
4744
end
45+
alias :fetch :[]
4846

4947
def has_key?(key)
5048
load_for_read!
51-
super(key.to_s)
49+
@data.has_key?(key.to_s)
5250
end
5351
alias :key? :has_key?
5452
alias :include? :has_key?
5553

5654
def []=(key, value)
5755
load_for_write!
58-
super(key.to_s, value)
56+
@data[key.to_s] = value
5957
end
58+
alias :store :[]=
6059

6160
def clear
6261
load_for_write!
63-
super
62+
@data.clear
6463
end
6564

6665
def destroy
@@ -70,29 +69,36 @@ def destroy
7069

7170
def to_hash
7271
load_for_read!
73-
Hash[self].delete_if { |k,v| v.nil? }
72+
@data.dup
7473
end
7574

7675
def update(hash)
7776
load_for_write!
78-
super(stringify_keys(hash))
77+
@data.update(stringify_keys(hash))
78+
end
79+
alias :merge! :update
80+
81+
def replace(hash)
82+
load_for_write!
83+
@data.replace(stringify_keys(hash))
7984
end
8085

8186
def delete(key)
8287
load_for_write!
83-
super(key.to_s)
88+
@data.delete(key.to_s)
8489
end
8590

8691
def inspect
8792
if loaded?
88-
super
93+
@data.inspect
8994
else
9095
"#<#{self.class}:0x#{self.object_id.to_s(16)} not yet loaded>"
9196
end
9297
end
9398

9499
def exists?
95100
return @exists if instance_variable_defined?(:@exists)
101+
@data = {}
96102
@exists = @by.send(:session_exists?, @env)
97103
end
98104

@@ -102,7 +108,7 @@ def loaded?
102108

103109
def empty?
104110
load_for_read!
105-
super
111+
@data.empty?
106112
end
107113

108114
private
@@ -117,7 +123,7 @@ def load_for_write!
117123

118124
def load!
119125
@id, session = @by.send(:load_session, @env)
120-
replace(stringify_keys(session))
126+
@data = stringify_keys(session)
121127
@loaded = true
122128
end
123129

@@ -297,7 +303,6 @@ def commit_session(env, status, headers, body)
297303
options = session.options
298304

299305
if options[:drop] || options[:renew]
300-
# if there is no session.id then we have nothing to destroy?!
301306
session_id = destroy_session(env, session.id || generate_sid, options)
302307
return [status, headers, body] unless session_id
303308
end
@@ -306,9 +311,9 @@ def commit_session(env, status, headers, body)
306311

307312
session.send(:load!) unless loaded_session?(session)
308313
session_id ||= session.id || generate_sid
309-
session = session.to_hash
314+
session_data = session.to_hash.delete_if { |k,v| v.nil? }
310315

311-
if not data = set_session(env, session_id, session, options)
316+
if not data = set_session(env, session_id, session_data, options)
312317
env["rack.errors"].puts("Warning! #{self.class.name} failed to save session. Content dropped.")
313318
elsif options[:defer] and not options[:renew]
314319
env["rack.errors"].puts("Defering cookie for #{session_id}") if $VERBOSE

0 commit comments

Comments
 (0)