Module: X::Resources::Identity

Included in:
X::Resource
Defined in:
x-resources/lib/x/resources/identity.rb

Overview

Equality and hashing by class and identifier, so the same resource fetched twice compares equal

Internal to x-resources: the methods it gives a resource, such as ==, are public API, but the module is only how they are shared, and which classes extend or include it can change within 1.x.

Instance Method Summary collapse

Instance Method Details

#==(other) ⇒ Boolean Also known as: eql?

Compare resources by class and identifier

Examples:

Compare users fetched in different requests

post.author == client.find_user("sferik")

Parameters:

  • other (Object) —

    the object to compare with

Returns:

  • (Boolean) —

    true if the other object is the same kind of resource with the same identifier



19
20
21
# File 'x-resources/lib/x/resources/identity.rb', line 19

def ==(other)
  self.class.equal?(other.class) && id.eql?(other.id)
end

#deconstruct_keys(keys) ⇒ Hash{Symbol => Object}

Deconstruct the resource into its attributes, so it matches a hash pattern

Every attribute the resource declares is read as its own method reads it, so a pattern sees the identifier as a number, a timestamp as a Time, and a metric by the name it is read by. A pattern can ask for an attribute by another name it is read by, such as retweet_count for repost_count, and a pattern that asks for every attribute, with a double splat, gets each once, by the name the resource declares.

Examples:

Match a post by its author

puts "by sferik" if post in {author_id: 7505382}

Match a post by a name from before posts were posts

puts "widely reposted" if post in {retweet_count: 100..}

Parameters:

  • keys (Array<Symbol>, nil) —

    the keys the pattern asks for, or nil for every attribute

Returns:

  • (Hash{Symbol => Object}) —

    the attributes



56
57
58
59
60
61
# File 'x-resources/lib/x/resources/identity.rb', line 56

def deconstruct_keys(keys)
  klass = self.class
  names = klass.__send__(:attribute_names)
  names = (names + klass.__send__(:attribute_aliases)) & keys unless keys.nil?
  names.to_h { |name| [name, public_send(name)] }
end

#hash ⇒ Integer

Hash resources by class and identifier

Examples:

Use resources as hash keys

{user => 1}[client.find_user("sferik")]

Returns:

  • (Integer) —

    the hash code



38
39
40
# File 'x-resources/lib/x/resources/identity.rb', line 38

def hash
  [self.class, id].hash
end