Skip to content

Instantly share code, notes, and snippets.

@markiz
Created August 11, 2011 16:11
Embed
What would you like to do?
JS-like hash objects
require "test/unit"
class JSHash < BasicObject
def initialize(hash = {})
@_attributes = hash.inject({}) do |res, (k, v)|
k = k.kind_of?(::Symbol) ? k.to_s : k
res[k] = v
res
end
end # initialize
def method_missing(message, *args, &block)
key = message.to_s
if key =~ /^(.*)=$/ # setter
@_attributes[$1] = args.first
else
if value = @_attributes[key]
if value.respond_to?(:call)
value.call(*args, &block)
else
value
end
else
nil
end
end
end # method_missing
def []=(key, value)
key = key.to_s if key.kind_of?(::Symbol)
@_attributes[key] = value
end # []=
def [](key)
@_attributes[key]
end # []
def respond_to?(message, include_private = false)
true
end # respond_to?
def _attributes
@_attributes
end # _attributes
end # class JSHash
class JavascriptLikeHashTest < Test::Unit::TestCase
def test_basic_initialization
hash = JSHash.new
assert_equal({}, hash._attributes)
end # test_basic_initialization
def test_initialization_from_hash
hash = JSHash.new("a" => 1)
assert_equal({"a" => 1}, hash._attributes)
end # test_initialization_from_hash
def test_initialization_from_hash_with_symbol_keys
hash = JSHash.new(:a => 1)
assert_equal({"a" => 1}, hash._attributes)
end # test_initialization_from_hash_with_symbol_keys
def test_assignment_via_bracket_equal
hash = JSHash.new
hash["hello"] = "world"
assert_equal({"hello" => "world"}, hash._attributes)
end # test_assignment_via_bracket_equal
def test_assignment_to_symbol_via_bracket_equal
hash = JSHash.new
hash[:hello] = "world"
assert_equal({"hello" => "world"}, hash._attributes)
end # test_assignment_to_symbol_via_bracket_equal
def test_retrieval_via_brackets
hash = JSHash.new("hello" => "world")
assert_equal(hash["hello"], "world")
end # test_retrieval_via_brackets
def test_retrieval_of_a_missing_key
hash = JSHash.new
assert_equal(nil, hash["hello"])
end # test_retrieval_of_a_missing_key
def test_retrieval_via_dot_notation
hash = JSHash.new
hash["hello"] = "world"
assert_equal("world", hash.hello)
assert_equal("world", hash["hello"])
end # test_retrieval_via_dot_notation
def test_assignment_via_dot_notation
hash = JSHash.new
hash.hello = "world"
assert_equal("world", hash.hello)
assert_equal("world", hash["hello"])
end # test_assignment_via_dot_notation
def test_method_call_via_dot_notation
hash = JSHash.new
hash.sqr = lambda {|x| x*x }
assert_equal(81, hash.sqr(9))
end # test_method_call_via_dot_notation
def test_retrieval_of_a_missing_member
hash = JSHash.new
assert_equal(nil, hash.sqr)
end # test_retrieval_of_a_missing_member
def test_respond_to
hash = JSHash.new
hash.hello = "world"
# We can always respond to any message
assert_equal true, hash.respond_to?(:hello)
assert_equal true, hash.respond_to?(:missing_method_name)
end # test_respond_to
end # class JavascriptLikeHashTest
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment