Class: Sawyer::Resource

Inherits:
Object
  • Object
show all
Defined in:
lib/sawyer/resource.rb

Constant Summary collapse

SPECIAL_METHODS =
Set.new(%w(agent rels fields))
ATTR_SETTER =
'='.freeze
ATTR_PREDICATE =
'?'.freeze

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(agent, data = {}) ⇒ Resource

Initializes a Resource with the given data.

agent - The Sawyer::Agent that made the API request. data - Hash of key/value properties.



13
14
15
16
17
18
19
20
21
22
23
24
25
# File 'lib/sawyer/resource.rb', line 13

def initialize(agent, data = {})
  @_agent  = agent
  data, links = agent.parse_links(data)
  @_rels = Relation.from_links(agent, links)
  @_fields = Set.new
  @_metaclass = (class << self; self; end)
  @attrs = {}
  data.each do |key, value|
    @_fields << key
    @attrs[key.to_sym] = process_value(value)
  end
  @_metaclass.send(:attr_accessor, *data.keys)
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(method, *args) ⇒ Object

Provides access to a resource’s attributes.



77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
# File 'lib/sawyer/resource.rb', line 77

def method_missing(method, *args)
  attr_name, suffix = method.to_s.scan(/([a-z0-9\_]+)(\?|\=)?$/i).first
  if suffix == ATTR_SETTER
    @_metaclass.send(:attr_accessor, attr_name)
    @_fields << attr_name.to_sym
    send(method, args.first)
  elsif attr_name && @_fields.include?(attr_name.to_sym)
    value = @attrs[attr_name.to_sym]
    case suffix
         when nil
           @_metaclass.send(:attr_accessor, attr_name)
           value
         when ATTR_PREDICATE then !!value
         end
  elsif suffix.nil? && SPECIAL_METHODS.include?(attr_name)
    instance_variable_get "@_#{attr_name}"
  elsif attr_name && !@_fields.include?(attr_name.to_sym)
    nil
  else
    super
  end
end

Instance Attribute Details

#_agentObject (readonly)

Returns the value of attribute _agent.



4
5
6
# File 'lib/sawyer/resource.rb', line 4

def _agent
  @_agent
end

#_fieldsObject (readonly)

Returns the value of attribute _fields.



4
5
6
# File 'lib/sawyer/resource.rb', line 4

def _fields
  @_fields
end

#_relsObject (readonly)

Returns the value of attribute _rels.



4
5
6
# File 'lib/sawyer/resource.rb', line 4

def _rels
  @_rels
end

#attrsObject (readonly) Also known as: to_hash, to_h

Returns the value of attribute attrs.



5
6
7
# File 'lib/sawyer/resource.rb', line 5

def attrs
  @attrs
end

Class Method Details

.attr_accessor(*attrs) ⇒ Object

Wire up accessor methods to pull from attrs



101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
# File 'lib/sawyer/resource.rb', line 101

def self.attr_accessor(*attrs)
  attrs.each do |attribute|
    class_eval do
      define_method attribute do
        @attrs[attribute.to_sym]
      end

      define_method "#{attribute}=" do |value|
        @attrs[attribute.to_sym] = value
      end

      define_method "#{attribute}?" do
        !!@attrs[attribute.to_sym]
      end
    end
  end
end

Instance Method Details

#[](method) ⇒ Object

Allow fields to be retrieved via Hash notation

method - key name

Returns the value from attrs if exists



55
56
57
58
59
# File 'lib/sawyer/resource.rb', line 55

def [](method)
  send(method.to_sym)
rescue NoMethodError
  nil
end

#[]=(method, value) ⇒ Object

Allow fields to be set via Hash notation

method - key name value - value to set for the attr key

Returns - value



67
68
69
70
71
# File 'lib/sawyer/resource.rb', line 67

def []=(method, value)
  send("#{method}=", value)
rescue NoMethodError
  nil
end

#inspectObject



119
120
121
# File 'lib/sawyer/resource.rb', line 119

def inspect
  to_attrs.respond_to?(:pretty_inspect) ? to_attrs.pretty_inspect : to_attrs.inspect
end

#key?(key) ⇒ Boolean

Checks to see if the given key is in this resource.

key - A Symbol key.

Returns true if the key exists, or false.

Returns:

  • (Boolean)


46
47
48
# File 'lib/sawyer/resource.rb', line 46

def key?(key)
  @_fields.include? key
end

#marshal_dumpObject



138
139
140
# File 'lib/sawyer/resource.rb', line 138

def marshal_dump
  [@attrs, @_fields, @_rels]
end

#marshal_load(dumped) ⇒ Object



142
143
144
# File 'lib/sawyer/resource.rb', line 142

def marshal_load(dumped)
  @attrs, @_fields, @_rels = *dumped.shift(3)
end

#process_value(value) ⇒ Object

Processes an individual value of this resource. Hashes get exploded into another Resource, and Arrays get their values processed too.

value - An Object value of a Resource’s data.

Returns an Object to set as the value of a Resource key.



33
34
35
36
37
38
39
# File 'lib/sawyer/resource.rb', line 33

def process_value(value)
  case value
  when Hash  then self.class.new(@_agent, value)
  when Array then value.map { |v| process_value(v) }
  else value
  end
end

#to_attrsObject



128
129
130
131
132
133
134
135
136
# File 'lib/sawyer/resource.rb', line 128

def to_attrs
  hash = self.attrs.clone
  hash.keys.each do |k|
    if hash[k].is_a?(Sawyer::Resource)
      hash[k] = hash[k].to_attrs
    end
  end
  hash
end

#to_yaml_propertiesObject

private



124
125
126
# File 'lib/sawyer/resource.rb', line 124

def to_yaml_properties
  [:@attrs, :@_fields, :@_rels]
end