Permalink
Browse files

Merge pull request #27 from wpeterson/master

Bundler and Suppressing Errors
  • Loading branch information...
2 parents 4519763 + f108bda commit ff02a801f72ab9ed7659fa34ee23039b79a569ae @binarylogic committed Jan 6, 2012
Showing with 88 additions and 10 deletions.
  1. +2 −1 .gitignore
  2. +6 −0 Gemfile
  3. +36 −0 Gemfile.lock
  4. +16 −0 README.rdoc
  5. +18 −4 lib/settingslogic.rb
  6. +4 −0 spec/settings4.rb
  7. +4 −0 spec/settingslogic_spec.rb
  8. +2 −5 spec/spec_helper.rb
View
3 .gitignore
@@ -5,4 +5,5 @@ pkg/*
coverage/*
doc/*
benchmarks/*
-
+.bundle
+vendor/bundle
View
6 Gemfile
@@ -0,0 +1,6 @@
+source "http://rubygems.org"
+
+gem 'rake', '0.8.7'
+gem 'jeweler'
+gem 'rspec', :require => 'spec'
+gem 'ruby-debug'
View
36 Gemfile.lock
@@ -0,0 +1,36 @@
+GEM
+ remote: http://rubygems.org/
+ specs:
+ columnize (0.3.6)
+ diff-lcs (1.1.3)
+ git (1.2.5)
+ jeweler (1.6.4)
+ bundler (~> 1.0)
+ git (>= 1.2.5)
+ rake
+ linecache (0.46)
+ rbx-require-relative (> 0.0.4)
+ rake (0.8.7)
+ rbx-require-relative (0.0.5)
+ rspec (2.8.0)
+ rspec-core (~> 2.8.0)
+ rspec-expectations (~> 2.8.0)
+ rspec-mocks (~> 2.8.0)
+ rspec-core (2.8.0)
+ rspec-expectations (2.8.0)
+ diff-lcs (~> 1.1.2)
+ rspec-mocks (2.8.0)
+ ruby-debug (0.10.4)
+ columnize (>= 0.1)
+ ruby-debug-base (~> 0.10.4.0)
+ ruby-debug-base (0.10.4)
+ linecache (>= 0.3)
+
+PLATFORMS
+ ruby
+
+DEPENDENCIES
+ jeweler
+ rake (= 0.8.7)
+ rspec
+ ruby-debug
View
16 README.rdoc
@@ -114,6 +114,22 @@ Modifying our model example:
This would allow you to specify a custom value for per_page just for posts, or
to fall back to your default value if not specified.
+=== 5. Suppressing Exceptions Conditionally
+
+Raising exceptions for missing settings helps highlight configuration problems. However, in a
+Rails app it may make sense to suppress this in production and return nil for missing settings.
+While it's useful to stop and highlight an error in development or test environments, this is
+often not the right answer for production.
+
+ class Settings < Settingslogic
+ source "#{Rails.root}/config/application.yml"
+ namespace Rails.env
+ suppress_errors Rails.env.production?
+ end
+
+ >> Settings.non_existent_key
+ => nil
+
== Note on Sinatra / Capistrano / Vlad
Each of these frameworks uses a +set+ convention for settings, which actually defines methods
View
22 lib/settingslogic.rb
@@ -35,7 +35,15 @@ def namespace(value = nil)
@namespace = value
end
end
-
+
+ def suppress_errors(value = nil)
+ if value.nil?
+ @suppress_errors
+ else
+ @suppress_errors = value
+ end
+ end
+
def [](key)
instance.fetch(key.to_s, nil)
end
@@ -104,7 +112,7 @@ def initialize(hash_or_file = self.class.source, section = nil)
else
hash = YAML.load(ERB.new(File.read(hash_or_file)).result).to_hash
if self.class.namespace
- hash = hash[self.class.namespace] or raise MissingSetting, "Missing setting '#{self.class.namespace}' in #{hash_or_file}"
+ hash = hash[self.class.namespace] or return missing_key("Missing setting '#{self.class.namespace}' in #{hash_or_file}")
end
self.replace hash
end
@@ -116,7 +124,7 @@ def initialize(hash_or_file = self.class.source, section = nil)
# Otherwise, create_accessors! (called by new) will have created actual methods for each key.
def method_missing(name, *args, &block)
key = name.to_s
- raise MissingSetting, "Missing setting '#{key}' in #{@section}" unless has_key? key
+ return missing_key("Missing setting '#{key}' in #{@section}") unless has_key? key
value = fetch(key)
create_accessor_for(key)
value.is_a?(Hash) ? self.class.new(value, "'#{key}' section in #{@section}") : value
@@ -152,10 +160,16 @@ def create_accessor_for(key, val=nil)
self.class.class_eval <<-EndEval
def #{key}
return @#{key} if @#{key}
- raise MissingSetting, "Missing setting '#{key}' in #{@section}" unless has_key? '#{key}'
+ return missing_key("Missing setting '#{key}' in #{@section}") unless has_key? '#{key}'
value = fetch('#{key}')
@#{key} = value.is_a?(Hash) ? self.class.new(value, "'#{key}' section in #{@section}") : value
end
EndEval
end
+
+ def missing_key(msg)
+ return nil if self.class.suppress_errors
+
+ raise MissingSetting, msg
+ end
end
View
4 spec/settings4.rb
@@ -0,0 +1,4 @@
+class Settings4 < Settingslogic
+ source "#{File.dirname(__FILE__)}/settings.yml"
+ suppress_errors true
+end
View
4 spec/settingslogic_spec.rb
@@ -107,6 +107,10 @@ class NoSource < Settingslogic; end
e.should_not be_nil
end
+ it "should allow suppressing errors" do
+ Settings4.non_existent_key.should be_nil
+ end
+
# This one edge case currently does not pass, because it requires very
# esoteric code in order to make it pass. It was judged not worth fixing,
# as it introduces significant complexity for minor gain.
View
7 spec/spec_helper.rb
@@ -1,18 +1,15 @@
-require 'spec'
-require 'rubygems'
-require 'ruby-debug' if RUBY_VERSION < '1.9' # ruby-debug does not work on 1.9.1 yet
-
$LOAD_PATH.unshift(File.dirname(__FILE__))
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
require 'settingslogic'
require 'settings'
require 'settings2'
require 'settings3'
+require 'settings4'
# Needed to test Settings3
Object.send :define_method, 'collides' do
'collision'
end
-Spec::Runner.configure do |config|
+RSpec.configure do |config|
end

0 comments on commit ff02a80

Please sign in to comment.