Skip to content

Instantly share code, notes, and snippets.

@dandorman
Created December 12, 2011 03:22
Show Gist options
  • Save dandorman/1464585 to your computer and use it in GitHub Desktop.
Save dandorman/1464585 to your computer and use it in GitHub Desktop.
EmptyArray: an array variant of the null object pattern
require 'minitest/autorun'
class EmptyArray
def self.new
@instance ||= super
end
private :initialize
def method_missing(*args, &block)
return empty_array.send(*args, &block) if empty_array.respond_to?(args.first)
self
end
def respond_to?(method_name)
true
end
private
def empty_array
@empty_array
end
end
describe EmptyArray do
it "returns itself until it gets a message a regular array responds to" do
empty_array = EmptyArray.new
empty_array.foo.bar.baz.qux.first.must_equal nil
end
it "returns [] when passed to Kernel#Array" do
Array(EmptyArray.new).must_equal []
end
it "returns [] when passed to Kernel#Array even after several chained methods" do
Array(EmptyArray.new.foo.bar.baz.qux).must_equal []
end
describe "cheesy singleton hack" do
it "is an instance of EmptyArray" do
EmptyArray.new.must_be_kind_of EmptyArray
end
it "one instance is the same as another" do
one = EmptyArray.new
two = EmptyArray.new
one.object_id.must_equal two.object_id
end
end
end
require 'test/unit/autorunner'
class EmptyArray
def self.new
@instance ||= super
end
private :initialize
def method_missing(*args, &block)
return empty_array.send(*args, &block) if empty_array.respond_to?(args.first)
self
end
def respond_to?(method_name)
true
end
private
def empty_array
@empty_array
end
end
class EmptyArrayTest < Test::Unit::TestCase
def test_returns_itself_until_it_gets_a_message_a_regular_array_responds_to
empty_array = EmptyArray.new
assert_nil empty_array.foo.bar.baz.qux.first
end
def test_returns_empty_array_when_passed_to_Kernel_Array
assert_equal [], Array(EmptyArray.new)
end
def test_returns_empty_array_when_passed_to_Kernel_Array_even_after_several_chained_methods
assert_equal [], Array(EmptyArray.new.foo.bar.baz.qux)
end
def test_is_an_instance_of_EmptyArray
assert_kind_of EmptyArray, EmptyArray.new
end
def test_one_instance_is_the_same_as_another
one = EmptyArray.new
two = EmptyArray.new
assert_same one, two
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment