Skip to content

Commit

Permalink
using a NilClass cache to improve performance
Browse files Browse the repository at this point in the history
fixed a bug where nil is returned instead of false
  • Loading branch information
marcbowes committed Mar 30, 2010
1 parent 590c028 commit f8128bc
Show file tree
Hide file tree
Showing 5 changed files with 23 additions and 8 deletions.
14 changes: 10 additions & 4 deletions lib/using_yaml.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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

Expand Down Expand Up @@ -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

Expand Down
1 change: 1 addition & 0 deletions lib/using_yaml/array.rb
Original file line number Diff line number Diff line change
Expand Up @@ -25,5 +25,6 @@ def self.add_array_extensions(array, pathname)

# Load in the extensions for this instance
array.extend(extensions)
array
end
end
4 changes: 3 additions & 1 deletion lib/using_yaml/hash.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -53,5 +54,6 @@ def self.add_hash_extensions(hash, pathname)

# Load in the extensions for this instance
hash.extend(extensions)
hash
end
end
5 changes: 3 additions & 2 deletions lib/using_yaml/nilclass.rb
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -29,5 +29,6 @@ def self.add_nilclass_extensions(instance, pathname)
end

instance.extend(extensions)
instance
end
end
7 changes: 6 additions & 1 deletion spec/using_yaml/using_yaml_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down

0 comments on commit f8128bc

Please sign in to comment.