Created
June 8, 2011 13:50
-
-
Save lhm/1014457 to your computer and use it in GitHub Desktop.
ruby spec and rubinius patch to allow object as hash key with protected hash method
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
From 510cbee3d1414cd4c5318ac135250e2e726bb593 Mon Sep 17 00:00:00 2001 | |
From: Lars Henrik Mai <lars.mai@kontinui.de> | |
Date: Wed, 8 Jun 2011 14:29:37 +0200 | |
Subject: [PATCH 1/2] Updated Hash constructor_spec to test for method visibility of hash | |
method when a key is an object | |
--- | |
spec/ruby/core/hash/constructor_spec.rb | 9 +++++++++ | |
spec/ruby/core/hash/fixtures/classes.rb | 6 ++++++ | |
2 files changed, 15 insertions(+), 0 deletions(-) | |
diff --git a/spec/ruby/core/hash/constructor_spec.rb b/spec/ruby/core/hash/constructor_spec.rb | |
index d8c2d2f..14b35a1 100644 | |
--- a/spec/ruby/core/hash/constructor_spec.rb | |
+++ b/spec/ruby/core/hash/constructor_spec.rb | |
@@ -49,4 +49,13 @@ describe "Hash.[]" do | |
hash_class[MyHash[1, 2]].class.should == hash_class | |
MyHash[hash_class[1, 2]].should be_kind_of(MyHash) | |
end | |
+ | |
+ it "ignores hash method visibility when key is an object" do | |
+ [:protected, :private].each do |v| | |
+ ObjectAsKey.send(v, :hash) | |
+ obj = ObjectAsKey.new | |
+ lambda { hash_class[obj,1] }.should_not raise_error(NoMethodError) | |
+ end | |
+ end | |
+ | |
end | |
diff --git a/spec/ruby/core/hash/fixtures/classes.rb b/spec/ruby/core/hash/fixtures/classes.rb | |
index 5d13ed6..d8bb54f 100644 | |
--- a/spec/ruby/core/hash/fixtures/classes.rb | |
+++ b/spec/ruby/core/hash/fixtures/classes.rb | |
@@ -20,6 +20,12 @@ class ToHashHash < hash_class | |
end | |
end | |
+class ObjectAsKey | |
+ def hash | |
+ 123456789 | |
+ end | |
+end | |
+ | |
module HashSpecs | |
def self.empty_frozen_hash | |
@empty ||= new_hash | |
-- | |
1.6.6 |
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
From 2939a54df31d2dad037362010977d6fa9db7439c Mon Sep 17 00:00:00 2001 | |
From: Lars Henrik Mai <lars.mai@kontinui.de> | |
Date: Wed, 8 Jun 2011 15:31:41 +0200 | |
Subject: [PATCH 2/2] Allow Hash[]= to work with objects as keys regardless of #hash method visibility | |
--- | |
kernel/common/hash.rb | 15 +++++++++++++-- | |
1 files changed, 13 insertions(+), 2 deletions(-) | |
diff --git a/kernel/common/hash.rb b/kernel/common/hash.rb | |
index 4b3106d..345ce21 100644 | |
--- a/kernel/common/hash.rb | |
+++ b/kernel/common/hash.rb | |
@@ -205,7 +205,7 @@ class Hash | |
redistribute @entries if @size > @max_entries | |
- key_hash = key.hash | |
+ key_hash = get_hash(key) | |
index = key_hash & @mask | |
entry = @entries[index] | |
@@ -377,7 +377,7 @@ class Hash | |
# Searches for an entry matching +key+. Returns the entry | |
# if found. Otherwise returns +nil+. | |
def find_entry(key) | |
- key_hash = key.hash | |
+ key_hash = get_hash(key) | |
entry = @entries[key_index(key_hash)] | |
while entry | |
@@ -388,6 +388,17 @@ class Hash | |
end | |
end | |
+ # get the hash of the key even if protected or private, but display a warning | |
+ def get_hash(key) | |
+ begin | |
+ key.hash | |
+ rescue(NoMethodError) | |
+ warn "calling protected or private method #{key.class}#hash on object #{key}, should be public" | |
+ key.__send__(:hash) | |
+ end | |
+ end | |
+ private :get_hash | |
+ | |
def index(value) | |
each_entry do |entry| | |
return entry.key if entry.value == value | |
-- | |
1.6.6 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment