Created
December 12, 2011 03:22
-
-
Save dandorman/1464585 to your computer and use it in GitHub Desktop.
EmptyArray: an array variant of the null object pattern
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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