Created
August 11, 2011 16:11
-
-
Save markiz/1140039 to your computer and use it in GitHub Desktop.
JS-like hash objects
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" | |
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