Skip to content

Commit

Permalink
Fixed that mash doesn't hash stuff consistently and thus makes it har…
Browse files Browse the repository at this point in the history
…d to use mashed objects with set and such. (technomancy)
  • Loading branch information
jnunemaker committed Apr 9, 2009
1 parent de57b1c commit 2da4913
Show file tree
Hide file tree
Showing 2 changed files with 17 additions and 2 deletions.
13 changes: 11 additions & 2 deletions lib/twitter/request.rb
Expand Up @@ -74,13 +74,22 @@ def parse(response)

def mash(obj)
if obj.is_a?(Array)
obj.map { |item| Mash.new(item) }
obj.map { |item| make_mash_with_consistent_hash(item) }
elsif obj.is_a?(Hash)
Mash.new(obj)
make_mash_with_consistent_hash(obj)
else
obj
end
end

# Lame workaround for the fact that mash doesn't hash correctly
def make_mash_with_consistent_hash(obj)
m = Mash.new(obj)
def m.hash
inspect.hash
end
return m
end

def to_query(options)
options.inject([]) do |collection, opt|
Expand Down
6 changes: 6 additions & 0 deletions test/twitter/base_test.rb
Expand Up @@ -69,6 +69,12 @@ class BaseTest < Test::Unit::TestCase
first.user.name.should == '-oAk-'
first.text.should == '@jnunemaker cold out today. cold yesterday. even colder today.'
end

should "correctly hash statuses" do
stub_get('/statuses/friends_timeline.json', 'friends_timeline.json')
hashes = @twitter.friends_timeline.map{ |s| s.hash }
hashes.should == @twitter.friends_timeline.map{ |s| s.hash }
end
end
end
end

7 comments on commit 2da4913

@technomancy
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually I did some digging and found out that it’s Ruby’s core Hash#hash that’s at fault; Mash only manifests this problem since it inherits from Hash.

The workaround to hash the inspect string works here, but unfortunately isn’t a good general-case fix because it honors insertion order, which should be irrelevant to the final hashed value.

@technomancy
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also: I’m curious what advantage Mash provides over OpenStruct, since that’s included in the standard library. It wouldn’t fix the #hash problem unfortunately, but it’d be one fewer dependency.

@jnunemaker
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I started with openstruct and I think the problem was that a hash of hashes doesn’t allow dot notation. Does that make sense? I’m open to other solutions if you come up with something.

@technomancy
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually using separate Twitter::Status classes made the most sense to me because it was most explicit. I suppose you’ve moved away from that because you’d rather let the API responses determine all the set of methods so you don’t have to update your code if the API changes?

@jnunemaker
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You are correct sir. I got tired of updating and pull in changes for every little tweak in the api.

@technomancy
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It’s too bad you can’t lock to a specific version of the REST API and only upgrade when you need a new piece of functionality.

@jnunemaker
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I would imagine eventually that twitter will no longer update the api so much. Right now it is still forming which makes changes more of an issue.

Please sign in to comment.