From f8128bc7a13abfb311fd5a73b92daa15c573b074 Mon Sep 17 00:00:00 2001 From: Marc Bowes Date: Tue, 30 Mar 2010 10:22:13 +0200 Subject: [PATCH] using a NilClass cache to improve performance fixed a bug where nil is returned instead of false --- lib/using_yaml.rb | 14 ++++++++++---- lib/using_yaml/array.rb | 1 + lib/using_yaml/hash.rb | 4 +++- lib/using_yaml/nilclass.rb | 5 +++-- spec/using_yaml/using_yaml_spec.rb | 7 ++++++- 5 files changed, 23 insertions(+), 8 deletions(-) diff --git a/lib/using_yaml.rb b/lib/using_yaml.rb index 41dfc21..0acdf3d 100644 --- a/lib/using_yaml.rb +++ b/lib/using_yaml.rb @@ -21,6 +21,8 @@ # # See +using_yaml+ for usage information. module UsingYAML + NilClass = add_nilclass_extensions(nil, nil) + class << self # Extends the incoming Array/Hash with magic which makes it # possible to +save+ and (in the case of Hashes) use methods @@ -31,10 +33,14 @@ def add_extensions(object, pathname = nil) add_array_extensions(object, pathname) when Hash add_hash_extensions(object, pathname) - when NilClass - add_nilclass_extensions(object, pathname) + when ::NilClass + if pathname + add_nilclass_extensions(object, pathname) + else + UsingYAML::NilClass + end end - + object end @@ -142,7 +148,7 @@ def using_yaml_file(filename) @using_yaml_cache[pathname] = UsingYAML.add_extensions(YAML.load_file(pathname), pathname) rescue Exception => e $stderr.puts "(UsingYAML) Could not load #{filename}: #{e.message}" unless UsingYAML.squelched? - UsingYAML.add_extensions(nil) + @using_yaml_cache[pathname] = UsingYAML.add_extensions(nil, pathname) end end diff --git a/lib/using_yaml/array.rb b/lib/using_yaml/array.rb index 2dbdd98..9b1900d 100644 --- a/lib/using_yaml/array.rb +++ b/lib/using_yaml/array.rb @@ -25,5 +25,6 @@ def self.add_array_extensions(array, pathname) # Load in the extensions for this instance array.extend(extensions) + array end end diff --git a/lib/using_yaml/hash.rb b/lib/using_yaml/hash.rb index 98535ec..674f00f 100644 --- a/lib/using_yaml/hash.rb +++ b/lib/using_yaml/hash.rb @@ -13,7 +13,8 @@ def self.add_hash_extensions(hash, pathname) name = args.shift.to_s if args.empty? - send(:[], name) || UsingYAML.add_extensions(nil) + value = send(:[], name) + value.nil? ? UsingYAML::NilClass : value elsif args.size == 1 && name =~ /(.+)=/ # This is an "alias" turning self.key= into self[key]= # Also extends the incoming value so that it behaves @@ -53,5 +54,6 @@ def self.add_hash_extensions(hash, pathname) # Load in the extensions for this instance hash.extend(extensions) + hash end end diff --git a/lib/using_yaml/nilclass.rb b/lib/using_yaml/nilclass.rb index 6444ab0..419d55e 100644 --- a/lib/using_yaml/nilclass.rb +++ b/lib/using_yaml/nilclass.rb @@ -1,10 +1,10 @@ module UsingYAML def self.add_nilclass_extensions(instance, pathname) extensions = Module.new do - define_method(:method_missing) do + define_method(:method_missing) do |*args| # Child objects should not have #save if respond_to? :save - add_extensions(nil) + UsingYAML::NilClass else # One nil is the same as the next :) self @@ -29,5 +29,6 @@ def self.add_nilclass_extensions(instance, pathname) end instance.extend(extensions) + instance end end diff --git a/spec/using_yaml/using_yaml_spec.rb b/spec/using_yaml/using_yaml_spec.rb index f4102af..3739668 100644 --- a/spec/using_yaml/using_yaml_spec.rb +++ b/spec/using_yaml/using_yaml_spec.rb @@ -11,7 +11,12 @@ end it "should gracefully handle nil.nil..." do - @person.children.invalid.call.should be_nil + @person.children.something.invalid.should be_nil + end + + it "should return false when expected" do + YAML.stubs(:load_file).with(anything).returns({ 'example' => false }) + @person.children.example.should == false end end