Module: Familia::Horreum::Serialization
- Included in:
- Familia::Horreum
- Defined in:
- lib/familia/horreum/serialization.rb
Overview
Serialization: Where Objects Go to Become Strings (and Vice Versa)!
This module is chock-full of methods that’ll make your head spin (in a good way)! We’ve got loaders, dumpers, and refreshers galore. It’s like a laundromat for your data, but instead of quarters, it runs on Redis commands.
A Note on Our Refreshing Refreshers: In the wild world of Ruby, ‘!’ usually means “Watch out! I’m dangerous!” But here in Familia-land, we march to the beat of a different drummer. Our refresh! method is the real deal, doing all the heavy lifting. The non-bang refresh? Oh, it’s just as rowdy, but it plays nice with method chaining. It’s like the polite twin who still knows how to party.
Remember: In Familia, refreshing isn’t just a chore, it’s a chance to dance with data! Whether you bang(!) or not, you’re still invited to the Redis disco.
(P.S. If you’re reading these docs, lol sorry. I asked Claude 3.5 to write in the style of _why the lucky stiff today and got this uncanny valley response. I hope you enjoy reading it as much as I did writing the prompt for it. - @delano).
(Ahem! What I meant to say was that if you’re reading this, congratulations! You’ve stumbled upon the secret garden of documentation. Feel free to smell the Ruby roses, but watch out for the Redis thorns!)
Instance Attribute Summary collapse
-
#redis ⇒ Redis
Summon the mystical Redis connection from the depths of instance or class.
Instance Method Summary collapse
-
#apply_fields(**fields) ⇒ self
Apply a smattering of fields to this object like fairy dust.
-
#commit_fields ⇒ Array<String>
Commit our precious fields to Redis.
-
#destroy! ⇒ void
Dramatically vanquish this object from the face of Redis! (ed: delete it).
-
#refresh ⇒ self
Refreshes the object’s state and returns self to allow method chaining.
-
#refresh! ⇒ Object
Refreshes the object’s state by querying Redis and overwriting the current field values.
-
#save ⇒ Boolean
Save our precious data to Redis, with a sprinkle of timestamp magic!.
-
#to_a ⇒ Array
Line up all our attributes in a neat little array parade!.
-
#to_h ⇒ Hash
Transform this object into a magical hash of wonders!.
-
#to_redis(val) ⇒ Object
The to_redis method in Familia::Redistype and Familia::Horreum serve similar purposes but have some key differences in their implementation:.
-
#transaction {|conn| ... } ⇒ Object
Perform a sacred Redis transaction ritual.
Instance Attribute Details
#redis ⇒ Redis
Summon the mystical Redis connection from the depths of instance or class.
This method is like a magical divining rod, always pointing to the nearest source of Redis goodness. It first checks if we have a personal Redis connection (@redis), and if not, it borrows the class’s connection.
51 52 53 |
# File 'lib/familia/horreum/serialization.rb', line 51 def redis @redis || self.class.redis end |
Instance Method Details
#apply_fields(**fields) ⇒ self
Apply a smattering of fields to this object like fairy dust.
134 135 136 137 138 139 140 |
# File 'lib/familia/horreum/serialization.rb', line 134 def apply_fields(**fields) fields.each do |field, value| # Whisper the new value into the object's ear (if it's listening) send("#{field}=", value) if respond_to?("#{field}=") end self end |
#commit_fields ⇒ Array<String>
Be warned, young programmer! This method dabbles in the arcane art of transactions. Side effects may include data persistence and a slight tingling sensation.
Commit our precious fields to Redis.
This method performs a sacred ritual, sending our cherished attributes on a journey through the ethernet to find their resting place in Redis.
160 161 162 163 164 165 166 167 168 169 170 |
# File 'lib/familia/horreum/serialization.rb', line 160 def commit_fields Familia.ld "[commit_fields] #{self.class} #{rediskey} #{to_h}" transaction do |conn| hmset # Only classes that have the expiration ferature enabled will # actually set an expiration time on their keys. Otherwise # this will be a no-op. update_expiration end end |
#destroy! ⇒ void
If debugging is enabled, this method will leave a trace of its destructive path, like breadcrumbs for future data archaeologists.
This method returns an undefined value.
Dramatically vanquish this object from the face of Redis! (ed: delete it)
This method is the doomsday device of our little data world. It will mercilessly eradicate all traces of our object from Redis, leaving naught but digital dust in its wake. Use with caution, lest you accidentally destroy the wrong data-verse!
191 192 193 194 |
# File 'lib/familia/horreum/serialization.rb', line 191 def destroy! Familia.trace :DESTROY, redis, redisuri, caller(1..1) if Familia.debug? delete! end |
#refresh ⇒ self
While this method allows chaining, it still performs a destructive update like refresh!.
Refreshes the object’s state and returns self to allow method chaining. This method calls refresh! internally, performing the actual Redis query and state update.
218 219 220 221 |
# File 'lib/familia/horreum/serialization.rb', line 218 def refresh refresh! self end |
#refresh! ⇒ Object
This is a destructive operation that will overwrite any unsaved changes.
Refreshes the object’s state by querying Redis and overwriting the current field values. This method performs a destructive update on the object, regardless of unsaved changes.
203 204 205 206 207 208 |
# File 'lib/familia/horreum/serialization.rb', line 203 def refresh! Familia.trace :REFRESH, redis, redisuri, caller(1..1) if Familia.debug? fields = hgetall Familia.ld "[refresh!] #{self.class} #{rediskey} #{fields.keys}" optimistic_refresh(**fields) end |
#save ⇒ Boolean
This method will leave breadcrumbs (traces) if you’re in debug mode. It’s like Hansel and Gretel, but for data operations!
Save our precious data to Redis, with a sprinkle of timestamp magic!
This method is like a conscientious historian, not only recording your object’s current state but also meticulously timestamping when it was created and last updated. It’s the record keeper of your data’s life story!
102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 |
# File 'lib/familia/horreum/serialization.rb', line 102 def save Familia.trace :SAVE, redis, redisuri, caller(1..1) if Familia.debug? # Update our object's life story self.key ||= self.identifier self.updated = Familia.now.to_i self.created ||= Familia.now.to_i # Commit our tale to the Redis chronicles ret = commit_fields # e.g. ["OK"] Familia.ld "[save] #{self.class} #{rediskey} #{ret}" # Did Redis accept our offering? ret.uniq.all? { |value| ["OK", true].include?(value) } end |
#to_a ⇒ Array
Each value is carefully disguised in its Redis costume
Line up all our attributes in a neat little array parade!
This method marshals all our object’s attributes into an orderly procession, ready to march into Redis in perfect formation. It’s like a little data army, but friendlier and less prone to conquering neighboring databases.
before joining the parade.
263 264 265 266 267 268 269 270 |
# File 'lib/familia/horreum/serialization.rb', line 263 def to_a self.class.fields.map do |field| val = send(field) prepared = to_redis(val) Familia.ld " [to_a] field: #{field} val: #{val.class} prepared: #{prepared.class}" prepared end end |
#to_h ⇒ Hash
Watch in awe as each field is lovingly prepared for its Redis adventure!
Transform this object into a magical hash of wonders!
This method performs an alchemical transmutation, turning our noble object into a more plebeian hash. But fear not, for in this form, it can slip through the cracks of the universe (or at least, into Redis) with ease.
238 239 240 241 242 243 244 245 246 |
# File 'lib/familia/horreum/serialization.rb', line 238 def to_h self.class.fields.inject({}) do |hsh, field| val = send(field) prepared = to_redis(val) Familia.ld " [to_h] field: #{field} val: #{val.class} prepared: #{prepared.class}" hsh[field] = prepared hsh end end |
#to_redis(val) ⇒ Object
The to_redis method in Familia::Redistype and Familia::Horreum serve similar purposes but have some key differences in their implementation:
Similarities:
-
Both methods aim to serialize various data types for Redis storage
-
Both handle basic data types like String, Symbol, and Numeric
-
Both have provisions for custom serialization methods
Differences:
-
Familia::Redistype uses the opts for type hints
-
Familia::Horreum had more explicit type checking and conversion
-
Familia::Redistype includes more extensive debug tracing
The centralized Familia.distinguisher method accommodates both approaches by:
-
Handling a wide range of data types, including those from both implementations
-
Providing a ‘strict_values’ option for flexible type handling
-
Supporting custom serialization through a dump_method
-
Including debug tracing similar to Familia::Redistype
By using Familia.distinguisher, we achieve more consistent behavior across different parts of the library while maintaining the flexibility to handle various data types and custom serialization needs. This centralization also makes it easier to extend or modify serialization behavior in the future.
299 300 301 302 303 304 305 306 307 308 309 310 311 |
# File 'lib/familia/horreum/serialization.rb', line 299 def to_redis(val) prepared = Familia.distinguisher(val, false) if prepared.nil? && val.respond_to?(dump_method) prepared = val.send(dump_method) end if prepared.nil? Familia.ld "[#{self.class}#to_redis] nil returned for #{self.class}##{name}" end prepared end |
#transaction {|conn| ... } ⇒ Object
This method temporarily replaces your Redis connection with a multi connection. Don’t worry, it puts everything back where it found it when it’s done.
Perform a sacred Redis transaction ritual.
This method creates a protective circle around your Redis operations, ensuring they all succeed or fail together. It’s like a group hug for your data operations, but with more ACID properties.
73 74 75 76 77 78 79 80 81 82 83 84 |
# File 'lib/familia/horreum/serialization.rb', line 73 def transaction original_redis = self.redis begin redis.multi do |conn| self.instance_variable_set(:@redis, conn) yield(conn) end ensure self.redis = original_redis end end |