twitter 5.0.0.rc.1 → 5.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (102) hide show
  1. data.tar.gz.sig +0 -0
  2. data/CHANGELOG.md +7 -1
  3. data/CONTRIBUTING.md +13 -15
  4. data/README.md +53 -33
  5. data/Rakefile +6 -0
  6. data/lib/twitter/arguments.rb +3 -0
  7. data/lib/twitter/base.rb +88 -89
  8. data/lib/twitter/client.rb +5 -41
  9. data/lib/twitter/configuration.rb +4 -5
  10. data/lib/twitter/core_ext/kernel.rb +5 -1
  11. data/lib/twitter/creatable.rb +6 -1
  12. data/lib/twitter/cursor.rb +16 -12
  13. data/lib/twitter/entity/uri.rb +2 -1
  14. data/lib/twitter/enumerable.rb +1 -1
  15. data/lib/twitter/error.rb +42 -39
  16. data/lib/twitter/factory.rb +12 -5
  17. data/lib/twitter/geo.rb +2 -7
  18. data/lib/twitter/geo_factory.rb +11 -7
  19. data/lib/twitter/geo_results.rb +12 -8
  20. data/lib/twitter/identity.rb +4 -12
  21. data/lib/twitter/list.rb +6 -3
  22. data/lib/twitter/media/photo.rb +5 -3
  23. data/lib/twitter/media_factory.rb +11 -7
  24. data/lib/twitter/null_object.rb +4 -3
  25. data/lib/twitter/place.rb +10 -16
  26. data/lib/twitter/profile_banner.rb +4 -5
  27. data/lib/twitter/rate_limit.rb +3 -0
  28. data/lib/twitter/relationship.rb +0 -9
  29. data/lib/twitter/rest/api/direct_messages.rb +9 -6
  30. data/lib/twitter/rest/api/favorites.rb +6 -11
  31. data/lib/twitter/rest/api/friends_and_followers.rb +6 -9
  32. data/lib/twitter/rest/api/lists.rb +27 -20
  33. data/lib/twitter/rest/api/oauth.rb +17 -0
  34. data/lib/twitter/rest/api/places_and_geo.rb +0 -18
  35. data/lib/twitter/rest/api/saved_searches.rb +6 -4
  36. data/lib/twitter/rest/api/suggested_users.rb +2 -2
  37. data/lib/twitter/rest/api/tweets.rb +7 -9
  38. data/lib/twitter/rest/api/users.rb +6 -6
  39. data/lib/twitter/rest/api/utils.rb +44 -17
  40. data/lib/twitter/rest/client.rb +25 -43
  41. data/lib/twitter/rest/response/parse_error_json.rb +15 -0
  42. data/lib/twitter/rest/response/parse_json.rb +5 -1
  43. data/lib/twitter/search_results.rb +12 -8
  44. data/lib/twitter/size.rb +2 -15
  45. data/lib/twitter/streaming/client.rb +23 -11
  46. data/lib/twitter/streaming/event.rb +35 -0
  47. data/lib/twitter/streaming/friend_list.rb +13 -0
  48. data/lib/twitter/streaming/message_parser.rb +18 -0
  49. data/lib/twitter/streaming/response.rb +4 -0
  50. data/lib/twitter/suggestion.rb +5 -10
  51. data/lib/twitter/token.rb +3 -1
  52. data/lib/twitter/trend.rb +2 -7
  53. data/lib/twitter/trend_results.rb +20 -14
  54. data/lib/twitter/tweet.rb +18 -23
  55. data/lib/twitter/user.rb +34 -19
  56. data/lib/twitter/version.rb +1 -1
  57. data/spec/fixtures/request_token.txt +6 -0
  58. data/spec/fixtures/track_streaming_user.json +5 -0
  59. data/spec/twitter/base_spec.rb +0 -16
  60. data/spec/twitter/basic_user_spec.rb +3 -3
  61. data/spec/twitter/cursor_spec.rb +4 -4
  62. data/spec/twitter/direct_message_spec.rb +9 -9
  63. data/spec/twitter/entity/uri_spec.rb +12 -11
  64. data/spec/twitter/geo/point_spec.rb +5 -5
  65. data/spec/twitter/geo/polygon_spec.rb +5 -5
  66. data/spec/twitter/geo_factory_spec.rb +2 -2
  67. data/spec/twitter/geo_spec.rb +6 -6
  68. data/spec/twitter/identifiable_spec.rb +5 -5
  69. data/spec/twitter/list_spec.rb +7 -7
  70. data/spec/twitter/media/photo_spec.rb +19 -18
  71. data/spec/twitter/media_factory_spec.rb +2 -2
  72. data/spec/twitter/null_object_spec.rb +7 -6
  73. data/spec/twitter/oembed_spec.rb +6 -6
  74. data/spec/twitter/place_spec.rb +37 -37
  75. data/spec/twitter/rate_limit_spec.rb +0 -17
  76. data/spec/twitter/relationship_spec.rb +4 -12
  77. data/spec/twitter/rest/api/direct_messages_spec.rb +8 -8
  78. data/spec/twitter/rest/api/friends_and_followers_spec.rb +50 -120
  79. data/spec/twitter/rest/api/geo_spec.rb +0 -14
  80. data/spec/twitter/rest/api/lists_spec.rb +39 -39
  81. data/spec/twitter/rest/api/oauth_spec.rb +15 -4
  82. data/spec/twitter/rest/api/saved_searches_spec.rb +6 -6
  83. data/spec/twitter/rest/api/tweets_spec.rb +6 -6
  84. data/spec/twitter/rest/api/users_spec.rb +4 -4
  85. data/spec/twitter/rest/client_spec.rb +9 -9
  86. data/spec/twitter/saved_search_spec.rb +5 -5
  87. data/spec/twitter/search_results_spec.rb +3 -3
  88. data/spec/twitter/settings_spec.rb +2 -2
  89. data/spec/twitter/size_spec.rb +5 -15
  90. data/spec/twitter/source_user_spec.rb +3 -3
  91. data/spec/twitter/streaming/client_spec.rb +33 -16
  92. data/spec/twitter/streaming/event_spec.rb +45 -0
  93. data/spec/twitter/suggestion_spec.rb +5 -15
  94. data/spec/twitter/target_user_spec.rb +3 -3
  95. data/spec/twitter/token_spec.rb +2 -2
  96. data/spec/twitter/trend_results_spec.rb +6 -6
  97. data/spec/twitter/trend_spec.rb +7 -17
  98. data/spec/twitter/tweet_spec.rb +31 -25
  99. data/spec/twitter/user_spec.rb +16 -16
  100. data/twitter.gemspec +5 -2
  101. metadata +67 -15
  102. metadata.gz.sig +0 -0
data.tar.gz.sig CHANGED
Binary file
@@ -8,12 +8,15 @@
8
8
  * [Remove `Twitter#from_user`](https://github.com/sferik/twitter/commit/d2ae9f1cc1f5224bcdff06cda65fabdf9e7fbcb3)
9
9
  * [Remove `ClientError`, `ServerError`, and `ParserError`](https://github.com/sferik/twitter/commit/72843948d8a6f66345adc254fa91cf1097592b22)
10
10
  * [Remove global configuration](https://github.com/sferik/twitter/commit/239c5a8462fabb8c8ef9ec6a4cdded34561d572d)
11
+ * [Remove ability to configure client with environment variables](https://github.com/sferik/twitter/commit/17e958579f65abf8932841f20058a5989abb994f)
12
+ * [Remove Brittish English aliases](https://github.com/sferik/twitter/commit/572813b373a1c3001ff6c1bb729f092434d17bab)
11
13
  * [Replace `multi_json` with `json`](https://github.com/sferik/twitter/commit/e5fc292fee078567664acf6be4ed31a8ad077780)
12
14
  * [Rename `oauth_token` to `access_token`](https://github.com/sferik/twitter/commit/d360f8015c487c4599460abd0dd0bc7e59a522a3)
13
15
  * [Move `Twitter::Arguments` out of `REST::API` namespace](https://github.com/sferik/twitter/commit/8faa15309d906dd46fccc1b914ea4aa7a5da7c2d)
14
16
  * [Move `Twitter::Client` into `REST` namespace](https://github.com/sferik/twitter/commit/5b8c3fd243227888fc0886b0bf864ecd3a018f99)
15
17
  * [Add `Twitter::Streaming::Client`](https://github.com/sferik/twitter/commit/23afe90aa494229a4389c3e51f753102b34fc551)
16
18
  * [Add `Twitter::Error::AlreadyPosted`](https://github.com/sferik/twitter/commit/e11d2a27dd0dfbbe16c812a81b9c2ab2852a7790)
19
+ * [Add `Twitter::REST::Client#reverse_token`](https://github.com/sferik/twitter/commit/39139c4df35b54b86fae29d1ac83a08f4aa293cd)
17
20
  * [Add `#url` methods to `Twitter::List`, `Twitter::Tweet`, and `Twitter::User`](https://github.com/sferik/twitter/commit/a89ec0f4e81097cc303b6c204e0375eb57ffd614)
18
21
  * [Add `Twitter::Place#contained_within` and `#contained_within?`](https://github.com/sferik/twitter/commit/23cc247bd20001ecbafa544bfb4546bdfc630429)
19
22
  * [Add `Twitter::GeoResults`](https://github.com/sferik/twitter/commit/be1a0a1425a6700267aae0f94a8835bff24dad56)
@@ -23,9 +26,12 @@
23
26
  * [Allow `URI` as argument](https://github.com/sferik/twitter/commit/c207567e674f108e4074e12c9e7343fb74e8a97c)
24
27
  * [Allow `String` in addition to `URI` objects](https://github.com/sferik/twitter/commit/89a46fbd3560109da87d5f87262dcf6bd2a336c6)
25
28
  * [Collection caching](https://github.com/sferik/twitter/commit/d484d7d7d7a0956f9b4fa6791a911ed7c9522cba)
26
- * [Memoize result within `Twitter::Base#new_or_null_object`](https://github.com/sferik/twitter/commit/45dd18a9feadbb56a60cea76424dd466d3e80c5e)
27
29
  * [Implement `Twitter::Cursor#each` without making an extra HTTP request](https://github.com/sferik/twitter/commit/8eeff57f5c6d6ca0a6f1ff5ebc31e652a71fc150)
28
30
  * [Make `Twitter::SearchResults` enumerable](https://github.com/sferik/twitter/commit/d5ce8537164912e79dffc5a054ecd9ae6ecb8075)
31
+ * [Make `Twitter::Base` objects immutable](https://github.com/sferik/twitter/commit/69b1ef7edad32398b778c8449bc3605739a6c59a)
32
+ * [Missing key now raises `KeyError`, not `ArgumentError`](https://github.com/sferik/twitter/commit/f56698caff608527b9f3c2c3dd4c18306589cb3b)
33
+ * [Use `equalizer` instead of manually overwriting #==](https://github.com/sferik/twitter/commit/a7ddf718b119e9c5fc8b87e6784e8c3304707a72)
34
+ * [Give methods more natural names](https://github.com/sferik/twitter/commit/e593194fb7bd689fca561e6334db1e6af622590a)
29
35
  * [Fix `Twitter::SearchResults#rpp` return value](https://github.com/sferik/twitter/commit/28d73200490ac2755c3e68d8d273fbc64a8d7066)
30
36
 
31
37
  4.8.1
@@ -1,25 +1,23 @@
1
1
  ## Contributing
2
2
  In the spirit of [free software][free-sw], **everyone** is encouraged to help
3
- improve this project.
3
+ improve this project. Here are some ways *you* can contribute:
4
4
 
5
5
  [free-sw]: http://www.fsf.org/licensing/essays/free-sw.html
6
6
 
7
- Here are some ways *you* can contribute:
8
-
9
- * by using alpha, beta, and prerelease versions
10
- * by reporting bugs
11
- * by suggesting new features
12
- * by writing or editing documentation
13
- * by writing specifications
14
- * by writing code (**no patch is too small**: fix typos, add comments, clean up
15
- inconsistent whitespace)
16
- * by refactoring code
17
- * by fixing [issues][]
18
- * by reviewing patches
19
- * [financially][pledgie]
7
+ * Use alpha, beta, and pre-release versions.
8
+ * Report bugs.
9
+ * Suggest new features.
10
+ * Write or edit documentation.
11
+ * Write specifications.
12
+ * Write code (**no patch is too small**: fix typos, add comments, clean up
13
+ inconsistent whitespace).
14
+ * Refactor code.
15
+ * Fix [issues][].
16
+ * Review patches.
17
+ * Financially pledge using [Pledgie][].
20
18
 
21
19
  [issues]: https://github.com/sferik/twitter/issues
22
- [pledgie]: http://pledgie.com/campaigns/18388
20
+ [Pledgie]: http://pledgie.com/campaigns/18388
23
21
 
24
22
  ## Submitting an Issue
25
23
  We use the [GitHub issue tracker][issues] to track bugs and features. Before
data/README.md CHANGED
@@ -74,17 +74,6 @@ client = Twitter::REST::Client.new do |config|
74
74
  end
75
75
  ```
76
76
 
77
- Alternately, you can configure a `Twitter::REST::Client` piecemeal, after it
78
- has been initialized, if that better suits your application:
79
-
80
- ```ruby
81
- client = Twitter::REST::Client.new
82
- client.consumer_key = "YOUR_CONSUMER_KEY"
83
- client.consumer_secret = "YOUR_CONSUMER_SECRET"
84
- client.access_token = "YOUR_ACCESS_TOKEN"
85
- client.access_token_secret = "YOUR_ACCESS_SECRET"
86
- ```
87
-
88
77
  Note: `oauth_token` has been renamed to `access_token` and `oauth_token_secret`
89
78
  is now `access_token_secret` to conform to the terminology used in Twitter's
90
79
  developer documentation.
@@ -119,7 +108,7 @@ and [Tony Arcieri][tarcieri] for helping to develop this feature.
119
108
  **Configuration works just like `Twitter::REST::Client`**
120
109
 
121
110
  ```ruby
122
- client = Twitter::Streaming::Client.new do
111
+ client = Twitter::Streaming::Client.new do |config|
123
112
  config.consumer_key = "YOUR_CONSUMER_KEY"
124
113
  config.consumer_secret = "YOUR_CONSUMER_SECRET"
125
114
  config.access_token = "YOUR_ACCESS_TOKEN"
@@ -144,17 +133,19 @@ client.sample do |tweet|
144
133
  end
145
134
  ```
146
135
 
147
- **Stream tweets for the authenticated user**
136
+ **Stream tweets, events and direct messages for the authenticated user**
148
137
 
149
138
  ```ruby
150
- client.user do |tweet|
151
- puts tweet.text
139
+ client.user do |message|
140
+ puts message
152
141
  end
153
142
  ```
154
143
 
155
- Currently, this library will only stream tweets. The goal is to eventually
156
- handle all [streaming message types][messages]. Patches that add support for a
157
- new message type would be appreciated.
144
+ `message` can be one of
145
+ + Twitter::Tweet
146
+ + Twitter::DirectMessage
147
+ + Twitter::Streaming::Event
148
+ + Twitter::Streaming::FriendList
158
149
 
159
150
  [messages]: https://dev.twitter.com/docs/streaming-apis/messages
160
151
 
@@ -250,7 +241,7 @@ simplicity and performance.
250
241
  </tr>
251
242
  <tr>
252
243
  <td>
253
- Collect your 20 most recent friends (twice).
244
+ Collect your 20 most recent friends twice.
254
245
  </td>
255
246
  <td>
256
247
  <pre><code lang="ruby">friends = client.friends
@@ -345,7 +336,7 @@ removed:
345
336
  * `#profile_image_url`
346
337
  * `#profile_image_url_https`
347
338
 
348
- These attributes can be accessed on the `Twitter::User` object, returned
339
+ These attributes can be accessed via the `Twitter::User` object, returned
349
340
  through the `#user` method.
350
341
 
351
342
  ### Users
@@ -354,8 +345,8 @@ been removed:
354
345
 
355
346
  * `#favorite_count` (use `#favorites_count`)
356
347
  * `#favoriters_count` (use `#favorites_count`)
357
- * `#favourite_count` (use `#favourites_count`)
358
- * `#favouriters_count` (use `#favourites_count`)
348
+ * `#favourite_count` (use `#favorites_count`)
349
+ * `#favouriters_count` (use `#favorites_count`)
359
350
  * `#follower_count` (use `#followers_count`)
360
351
  * `#friend_count` (use `#friends_count`)
361
352
  * `#status_count` (use `#statuses_count`)
@@ -364,6 +355,30 @@ been removed:
364
355
  * `#updates_count` (use `#tweets_count`)
365
356
  * `#translator` (use `#translator?`)
366
357
 
358
+ ### Remove British English aliases
359
+ Earlier versions of this library aliased `favourites` to `favorites`. These
360
+ aliases have been removed. Ruby is implemented in American English. The
361
+ `initialize` method is spelled with a "z", not an "s", and Ruby provides no
362
+ alias. Likewise, this library does not provide aliases for Commonwealthers.
363
+ Merica. :us:
364
+
365
+ ### More natural method names
366
+ All create, destroy, add, and remove methods have been renamed to put the verb
367
+ at the beginning:
368
+
369
+ * `#direct_message_create` is now `#create_direct_message`
370
+ * `#direct_message_destroy` is now `#destroy_direct_message`
371
+ * `#list_create` is now `#create_list`
372
+ * `#list_destroy` is now `#destroy_list`
373
+ * `#list_remove_member` is now `#remove_list_member`
374
+ * `#list_remove_members` is now `#remove_list_members`
375
+ * `#list_add_member` is now `#add_list_member`
376
+ * `#list_add_members` is now `#add_list_members`
377
+ * `#lists_owned` is now `#owned_list`
378
+ * `#saved_search_create` is now `#create_saved_search`
379
+ * `#saved_search_destroy` is now `#destroy_saved_search`
380
+ * `#status_destroy` is now `#destroy_status`
381
+
367
382
  ### Errors
368
383
  The `Twitter::Error::ClientError` and `Twitter::Error::ServerError` class
369
384
  hierarchy has been removed. All errors now inherit directly from
@@ -432,20 +447,13 @@ You can pass configuration options as a block to `Twitter::REST::Client.new`.
432
447
 
433
448
  ```ruby
434
449
  client = Twitter::REST::Client.new do |config|
435
- config.consumer_key = YOUR_APP_CONSUMER_KEY
436
- config.consumer_secret = YOUR_APP_CONSUMER_SECRET
437
- config.access_token = A_USER_ACCESS_TOKEN
438
- config.access_token_secret = A_USER_ACCESS_SECRET
450
+ config.consumer_key = "YOUR_CONSUMER_KEY"
451
+ config.consumer_secret = "YOUR_CONSUMER_SECRET"
452
+ config.access_token = "YOUR_ACCESS_TOKEN"
453
+ config.access_token_secret = "YOUR_ACCESS_SECRET"
439
454
  end
440
455
  ```
441
456
 
442
- Alternately, you can set the following environment variables:
443
-
444
- TWITTER_CONSUMER_KEY
445
- TWITTER_CONSUMER_SECRET
446
- TWITTER_ACCESS_TOKEN
447
- TWITTER_ACCESS_TOKEN_SECRET
448
-
449
457
  After configuration, requests can be made like so:
450
458
 
451
459
  ```ruby
@@ -548,6 +556,18 @@ client.search("#ruby -rt", :lang => "ja").first.text
548
556
  ```
549
557
  For more usage examples, please see the full [documentation][].
550
558
 
559
+ ## Object Graph
560
+
561
+ ![Entity-relationship diagram][erd]
562
+
563
+ [erd]: https://github.com/sferik/twitter/raw/master/etc/erd.png "Entity-relationship diagram"
564
+
565
+ This entity-relationship diagram is generated programatically. If you add or
566
+ remove any Twitter objects, please regenerate the ERD with the following
567
+ command:
568
+
569
+ bundle exec rake erd
570
+
551
571
  ## Supported Ruby Versions
552
572
  This library aims to support and is [tested against][travis] the following Ruby
553
573
  implementations:
data/Rakefile CHANGED
@@ -7,5 +7,11 @@ RSpec::Core::RakeTask.new(:spec)
7
7
  task :test => :spec
8
8
  task :default => :spec
9
9
 
10
+ task :erd do
11
+ `bundle exec ruby ./etc/erd.rb > ./etc/erd.dot`
12
+ `dot -Tpng ./etc/erd.dot -o ./etc/erd.png`
13
+ `open ./etc/erd.png`
14
+ end
15
+
10
16
  require 'yard'
11
17
  YARD::Rake::YardocTask.new
@@ -2,6 +2,9 @@ module Twitter
2
2
  class Arguments < Array
3
3
  attr_reader :options
4
4
 
5
+ # Initializes a new Arguments object
6
+ #
7
+ # @return [Twitter::Arguments]
5
8
  def initialize(args)
6
9
  @options = args.last.is_a?(::Hash) ? args.pop : {}
7
10
  super(args)
@@ -1,106 +1,116 @@
1
1
  require 'forwardable'
2
+ require 'memoizable'
2
3
  require 'twitter/null_object'
3
4
  require 'uri'
4
5
 
5
6
  module Twitter
6
7
  class Base
7
8
  extend Forwardable
9
+ include Memoizable
8
10
  attr_reader :attrs
9
11
  alias to_h attrs
10
12
  alias to_hash attrs
11
13
  alias to_hsh attrs
12
- def_delegators :attrs, :delete, :update
13
14
 
14
- # Define methods that retrieve the value from attributes
15
- #
16
- # @param attrs [Array, Symbol]
17
- def self.attr_reader(*attrs)
18
- attrs.each do |attr|
19
- define_attribute_method(attr)
20
- define_predicate_method(attr)
15
+ class << self
16
+
17
+ # Construct an object from a response hash
18
+ #
19
+ # @param response [Hash]
20
+ # @return [Twitter::Base]
21
+ def from_response(response={})
22
+ new(response[:body])
21
23
  end
22
- end
23
24
 
24
- # Define object methods from attributes
25
- #
26
- # @param klass [Symbol]
27
- # @param key1 [Symbol]
28
- # @param key2 [Symbol]
29
- def self.object_attr_reader(klass, key1, key2=nil)
30
- define_attribute_method(key1, klass, key2)
31
- define_predicate_method(key1)
32
- end
25
+ # Define methods that retrieve the value from attributes
26
+ #
27
+ # @param attrs [Array, Symbol]
28
+ def attr_reader(*attrs)
29
+ attrs.each do |attr|
30
+ define_attribute_method(attr)
31
+ define_predicate_method(attr)
32
+ end
33
+ end
33
34
 
34
- # Define URI methods from attributes
35
- #
36
- # @param attrs [Array, Symbol]
37
- def self.uri_attr_reader(*attrs)
38
- attrs.each do |uri_key|
39
- array = uri_key.to_s.split("_")
40
- index = array.index("uri")
41
- array[index] = "url"
42
- url_key = array.join("_").to_sym
43
- define_uri_method(uri_key, url_key)
44
- define_predicate_method(uri_key, url_key)
45
- alias_method(url_key, uri_key)
46
- alias_method("#{url_key}?", "#{uri_key}?")
35
+ # Define object methods from attributes
36
+ #
37
+ # @param klass [Symbol]
38
+ # @param key1 [Symbol]
39
+ # @param key2 [Symbol]
40
+ def object_attr_reader(klass, key1, key2=nil)
41
+ define_attribute_method(key1, klass, key2)
42
+ define_predicate_method(key1)
47
43
  end
48
- end
49
44
 
50
- # Dynamically define a method for a URI
51
- #
52
- # @param key1 [Symbol]
53
- # @param key2 [Symbol]
54
- def self.define_uri_method(key1, key2)
55
- define_method(key1) do
56
- memoize(key1) do
57
- ::URI.parse(@attrs[key2]) if @attrs[key2]
45
+ # Define URI methods from attributes
46
+ #
47
+ # @param attrs [Array, Symbol]
48
+ def uri_attr_reader(*attrs)
49
+ attrs.each do |uri_key|
50
+ array = uri_key.to_s.split("_")
51
+ index = array.index("uri")
52
+ array[index] = "url"
53
+ url_key = array.join("_").to_sym
54
+ define_uri_method(uri_key, url_key)
55
+ alias_method(url_key, uri_key)
56
+ define_predicate_method(uri_key, url_key)
57
+ alias_method(:"#{url_key}?", :"#{uri_key}?")
58
58
  end
59
59
  end
60
- end
61
60
 
62
- # Dynamically define a method for an attribute
63
- #
64
- # @param key1 [Symbol]
65
- # @param klass [Symbol]
66
- # @param key2 [Symbol]
67
- def self.define_attribute_method(key1, klass=nil, key2=nil)
68
- define_method(key1) do
69
- memoize(key1) do
61
+ # Define display_uri attribute methods
62
+ def display_uri_attr_reader
63
+ define_attribute_method(:display_url)
64
+ alias_method(:display_uri, :display_url)
65
+ define_predicate_method(:display_uri, :display_url)
66
+ alias_method(:display_url?, :display_uri?)
67
+ end
68
+
69
+ private
70
+
71
+ # Dynamically define a method for a URI
72
+ #
73
+ # @param key1 [Symbol]
74
+ # @param key2 [Symbol]
75
+ def define_uri_method(key1, key2)
76
+ define_method(key1) do ||
77
+ URI.parse(@attrs[key2]) if @attrs[key2]
78
+ end
79
+ memoize(key1)
80
+ end
81
+
82
+ # Dynamically define a method for an attribute
83
+ #
84
+ # @param key1 [Symbol]
85
+ # @param klass [Symbol]
86
+ # @param key2 [Symbol]
87
+ def define_attribute_method(key1, klass=nil, key2=nil)
88
+ define_method(key1) do ||
70
89
  if klass.nil?
71
90
  @attrs[key1]
72
91
  else
73
92
  if @attrs[key1]
74
- if key2.nil?
75
- Twitter.const_get(klass).new(@attrs[key1])
76
- else
77
- attrs = @attrs.dup
78
- value = attrs.delete(key1)
79
- Twitter.const_get(klass).new(value.update(key2 => attrs))
80
- end
93
+ attrs = attrs_for_object(key1, key2)
94
+ Twitter.const_get(klass).new(attrs)
81
95
  else
82
- Twitter::NullObject.instance
96
+ NullObject.new
83
97
  end
84
98
  end
85
99
  end
100
+ memoize(key1)
86
101
  end
87
- end
88
102
 
89
- # Dynamically define a predicate method for an attribute
90
- #
91
- # @param key [Symbol]
92
- def self.define_predicate_method(key1, key2=key1)
93
- define_method(:"#{key1}?") do
94
- !!@attrs[key2]
103
+ # Dynamically define a predicate method for an attribute
104
+ #
105
+ # @param key1 [Symbol]
106
+ # @param key2 [Symbol]
107
+ def define_predicate_method(key1, key2=key1)
108
+ define_method(:"#{key1}?") do ||
109
+ !!@attrs[key2]
110
+ end
111
+ memoize(:"#{key1}?")
95
112
  end
96
- end
97
113
 
98
- # Construct an object from a response hash
99
- #
100
- # @param response [Hash]
101
- # @return [Twitter::Base]
102
- def self.from_response(response={})
103
- new(response[:body])
104
114
  end
105
115
 
106
116
  # Initializes a new object
@@ -120,26 +130,15 @@ module Twitter
120
130
  nil
121
131
  end
122
132
 
123
- def memoize(key, &block)
124
- ivar = :"@#{key}"
125
- return instance_variable_get(ivar) if instance_variable_defined?(ivar)
126
- result = block.call
127
- instance_variable_set(ivar, result)
128
- end
129
-
130
133
  private
131
134
 
132
- # @param attr [Symbol]
133
- # @param other [Twitter::Base]
134
- # @return [Boolean]
135
- def attr_equal(attr, other)
136
- self.class == other.class && !other.send(attr.to_sym).nil? && send(attr.to_sym) == other.send(attr.to_sym)
137
- end
138
-
139
- # @param other [Twitter::Base]
140
- # @return [Boolean]
141
- def attrs_equal(other)
142
- self.class == other.class && !other.attrs.empty? && attrs == other.attrs
135
+ def attrs_for_object(key1, key2=nil)
136
+ if key2.nil?
137
+ @attrs[key1]
138
+ else
139
+ attrs = @attrs.dup
140
+ attrs.delete(key1).merge(key2 => attrs)
141
+ end
143
142
  end
144
143
 
145
144
  end