From f18f60f79a8145b40b05f0dafc6d57302b28e0d0 Mon Sep 17 00:00:00 2001 From: Jip van Reijsen Date: Wed, 3 Dec 2014 02:07:49 +0100 Subject: [PATCH] Attempt to look up non-existing settings in parent classes (see #21) This fixes an issue where settings are added to Cuba.settings *after* inheriting from `Cuba` are not picked up by the child classes. The problem is described in issue #21. If a setting does not exist, Settings are looked up in the settings Hash of the parent class using `Hash#default_proc`. The settings Hash is still deepcloned, so settings are still overridable. --- lib/cuba.rb | 17 ++++++++++++++++- test/settings.rb | 16 ++++++++++++++++ 2 files changed, 32 insertions(+), 1 deletion(-) diff --git a/lib/cuba.rb b/lib/cuba.rb index 32258bb9..87a0b4df 100644 --- a/lib/cuba.rb +++ b/lib/cuba.rb @@ -86,11 +86,26 @@ def self.settings end def self.deepclone(obj) - Marshal.load(Marshal.dump(obj)) + # Hashes with a default_proc cannot be serialized by Marshal.dump. + if obj.respond_to?(:default_proc) + proc = obj.default_proc + obj.default_proc = nil + end + + new_obj = Marshal.load(Marshal.dump(obj)) + + if obj.respond_to?(:default_proc) + obj.default_proc = proc + end + + new_obj end def self.inherited(child) child.settings.replace(deepclone(settings)) + child.settings.default_proc = proc do |hash,key| + hash[key] = self.settings[key] + end end attr :env diff --git a/test/settings.rb b/test/settings.rb index 0bff575f..14553309 100644 --- a/test/settings.rb +++ b/test/settings.rb @@ -18,6 +18,22 @@ class Admin < Cuba; end assert_equal "baz", Admin.settings[:foo] end +test "attempts to get absent settings from parent class" do + class User < Cuba; end + class PowerUser < User; end + + Cuba.settings[:get_from_parent] = "x" + + assert_equal nil, Cuba.settings[:does_not_exist] + assert_equal nil, User.settings[:absent] + assert_equal "x", User.settings[:get_from_parent] + assert_equal "x", PowerUser.settings[:get_from_parent] + + Cuba.settings[:after_deepcloning] = "x" + + assert_equal "x", User.settings[:after_deepcloning] +end + test do Cuba.settings[:hello] = "Hello World"