Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

Fix Array#flatten on an array containing a Settingslogic object... #36

Open
wants to merge 1 commit into from
@hypomodern

...by delegating method_missing to Hash in the specific case.

On newer rubies, Array#flatten calls #to_ary on everything in the array, which raises a MissingSetting error from a Settingslogic object. This was reported as an rspec-core issue, but is more a ruby/settingslogic deal.

At any rate, you'd see an unhandled Settingslogic::MissingSetting: Missing setting 'to_ary' if you happened to have a Settingslogic object in an array that got flattened.

This is particularly a pain point with newer rspec. See rspec/rspec-core#620 for the initial bug report, which was referred to Settingslogic for a fix. I concur.

My editor hates trailing whitespace, so that's redacted in there too :).

@hypomodern hypomodern Fix Array#flatten on an array containing a Settingslogic object by de…
…legating method_missing to Hash in the specific case.

On newer rubies, Array#flatten calls #to_ary on everything in the array, which causes a MissingSetting error from a Settingslogic object. This was reported as an rspec-core issue, but is more a ruby/settingslogic deal.
d623622
@jhwist

I'm +1 for this as it currently bites me.

@srikanthjeeva

+1 .. break my build too.

@glennr

+1

@rpcolom

+1

@glennr

Interestingly, after monkey-patching this I got

/usr/local/opt/rbenv/versions/1.9.3-p374/lib/ruby/gems/1.9.1/gems/settingslogic-2.0.8/lib/settingslogic.rb:173:in missing_key': Missing setting 'to_str' in /Users/glennr/git/blah/config/models/debit_order_rejection_settings.yml (Settingslogic::MissingSetting)
from /Users/glennr/git/blah/spec/support/settingslogic_rspec1_hack.rb:14:in
method_missing'
from /usr/local/opt/rbenv/versions/1.9.3-p374/lib/ruby/gems/1.9.1/gems/settingslogic-2.0.8/lib/settingslogic.rb:77:in method_missing'
from /usr/local/opt/rbenv/versions/1.9.3-p374/lib/ruby/gems/1.9.1/gems/rspec-1.3.1/lib/spec/example/example_group_hierarchy.rb:49:in
join'

So I ended up adding

super if name === :to_str # delegate to Hash

ie.

class Settingslogic < Hash                                                                                             

  def method_missing(name, *args, &block)                                                                              
    super if name === :to_ary # delegate to Hash                                                                       
    super if name === :to_str # delegate to Hash                                                                       
    key = name.to_s                                                                                                    
    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                               
  end                                                                                                                  

end 
@hirakiuc

+1

@bawigga

+1

@kidlab

I got the same issue. +1

@mikegee

+1 from me, too.

Is there anything we can do to help get this merged?

@Spone

+1 same issue here

@weilu weilu referenced this pull request from a commit in peatio/peatio
@weilu weilu monkey patch settingslogic see binarylogic/settingslogic#36 e29face
@weilu weilu referenced this pull request from a commit in peatio/peatio
@weilu weilu monkey patch settingslogic see binarylogic/settingslogic#36 559ccb6
@weilu weilu referenced this pull request from a commit in peatio/peatio
@weilu weilu monkey patch settingslogic see binarylogic/settingslogic#36 9ba2608
@weilu weilu referenced this pull request from a commit in peatio/peatio
@weilu weilu monkey patch settingslogic see binarylogic/settingslogic#36 c2407c9
@mguymon mguymon referenced this pull request from a commit in mguymon/settingslogic
@mguymon mguymon delegate to_ary to Hash from binarylogic/settingslogic#36 52c985d
@gitman gitman referenced this pull request from a commit in gitman/settingslogic
@gitman gitman missing_key': Missing setting 'to_ary' in (Settingslogic::MissingSett…
…ing)

Fix Array#flatten on an array containing a Settingslogic object
binarylogic#36
3282d76
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Aug 15, 2012
  1. @hypomodern

    Fix Array#flatten on an array containing a Settingslogic object by de…

    hypomodern authored
    …legating method_missing to Hash in the specific case.
    
    On newer rubies, Array#flatten calls #to_ary on everything in the array, which causes a MissingSetting error from a Settingslogic object. This was reported as an rspec-core issue, but is more a ruby/settingslogic deal.
This page is out of date. Refresh to see the latest.
View
2  Gemfile
@@ -3,7 +3,7 @@ source "http://rubygems.org"
group :development do
gem 'rake'
gem 'jeweler'
- gem 'rspec', :require => 'spec'
+ gem 'rspec'
gem 'rcov'
if RUBY_VERSION < "1.9"
gem 'ruby-debug'
View
39 Gemfile.lock
@@ -1,6 +1,7 @@
GEM
remote: http://rubygems.org/
specs:
+ archive-tar-minitar (0.5.2)
columnize (0.3.6)
diff-lcs (1.1.3)
git (1.2.5)
@@ -8,24 +9,28 @@ GEM
bundler (~> 1.0)
git (>= 1.2.5)
rake
- linecache (0.46)
- rbx-require-relative (> 0.0.4)
+ linecache19 (0.5.12)
+ ruby_core_source (>= 0.1.4)
rake (0.9.2.2)
- rbx-require-relative (0.0.5)
rcov (0.9.11)
- 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)
+ rspec (2.11.0)
+ rspec-core (~> 2.11.0)
+ rspec-expectations (~> 2.11.0)
+ rspec-mocks (~> 2.11.0)
+ rspec-core (2.11.1)
+ rspec-expectations (2.11.2)
+ diff-lcs (~> 1.1.3)
+ rspec-mocks (2.11.2)
+ ruby-debug-base19 (0.11.25)
+ columnize (>= 0.3.1)
+ linecache19 (>= 0.5.11)
+ ruby_core_source (>= 0.1.4)
+ ruby-debug19 (0.11.6)
+ columnize (>= 0.3.1)
+ linecache19 (>= 0.5.11)
+ ruby-debug-base19 (>= 0.11.19)
+ ruby_core_source (0.1.5)
+ archive-tar-minitar (>= 0.5.2)
PLATFORMS
ruby
@@ -35,4 +40,4 @@ DEPENDENCIES
rake
rcov
rspec
- ruby-debug
+ ruby-debug19
View
7 lib/settingslogic.rb
@@ -60,12 +60,12 @@ def load!
instance
true
end
-
+
def reload!
@instance = nil
load!
end
-
+
private
def instance
return @instance if @instance
@@ -73,7 +73,7 @@ def instance
create_accessors!
@instance
end
-
+
def method_missing(name, *args, &block)
instance.send(name, *args, &block)
end
@@ -124,6 +124,7 @@ def initialize(hash_or_file = self.class.source, section = nil)
# Called for dynamically-defined keys, and also the first key deferenced at the top-level, if load! is not used.
# Otherwise, create_accessors! (called by new) will have created actual methods for each key.
def method_missing(name, *args, &block)
+ super if name === :to_ary # delegate to_ary to Hash
key = name.to_s
return missing_key("Missing setting '#{key}' in #{@section}") unless has_key? key
value = fetch(key)
View
19 spec/settingslogic_spec.rb
@@ -4,11 +4,11 @@
it "should access settings" do
Settings.setting2.should == 5
end
-
+
it "should access nested settings" do
Settings.setting1.setting1_child.should == "saweet"
end
-
+
it "should access deep nested settings" do
Settings.setting1.deep.another.should == "my value"
end
@@ -35,7 +35,7 @@
Settings.language.haskell.paradigm.should == 'functional'
Settings.language.smalltalk.paradigm.should == 'object oriented'
end
-
+
it "should not collide with global methods" do
Settings3.nested.collides.does.should == 'not either'
Settings3[:nested] = 'fooey'
@@ -73,7 +73,7 @@
end
e.should_not be_nil
e.message.should =~ /Missing setting 'erlang' in 'language' section/
-
+
Settings.language['erlang'].should be_nil
Settings.language['erlang'] = 5
Settings.language['erlang'].should == 5
@@ -158,5 +158,14 @@ class NoSource < Settingslogic; end
it "should be a hash" do
Settings.send(:instance).should be_is_a(Hash)
end
-
+
+ # rspec-core issue 620
+ it "should not blow up if #to_ary is called on it via Array#flatten" do
+ lambda {
+ [ Settings, ['a'] ].flatten
+ }.should_not raise_error
+
+ [Settings, ['a']].flatten.should == [Settings, 'a']
+ end
+
end
Something went wrong with that request. Please try again.