MagicArray
MagicArray is class that performs lazy loading of data. The only thing that you have to do is to define data source methods inside the MagicArray descendant. And then you can simply load data by accessing array elements.
Installation
Add this line to your application's Gemfile:
gem 'magic_array'
And then execute:
$ bundle
Or install it yourself as:
$ gem install magic_array
Usage
Say you want to load some posts from vk.com. You can simply create the MagicArray descendant in order to load them.
You should always remember that you have to define element_source(index) and elements_source(range_start, count) using MagicArray.
MagicArray descendant example:
class PostArray < MagicArray
load_limit 100
def initialize group_id
@group_id = "-#{group_id}"
self.count = vk.wall.get(owner_id: @group_id, offset: 0, count: 1).first
super
end
def element_source index
vk.wall.get(owner_id: @group_id, offset: index, count: 1).last
end
def elements_source range_start, range_count
result = vk.wall.get(owner_id: @group_id, offset: range_start, count: range_count)
result.shift
result
end
def vk
vk_source = -> {VK::Client.new}
@vk ||= vk_source.call
end
def search from, till
from_index = (bsearch{ |post| post.date <= from }) - 1
till_index = bsearch{ |post| post.date <= till }
self[till_index..from_index]
end
private
def bsearch &block
first = 0
last = count-1
mid = first + (last - first) / 2
while first<last
if yield(self[mid])
last = mid
else
first = mid + 1
end
mid = first + (last - first) / 2
end
if yield(self[last])
last
else
nil
end
end
end
###Initializing object
post_array = PostArray.new 1234567
=> #<PostArray:0x000000028d3568 @group_id="-17076618", @vk=#<VkontakteApi::Client:0x000000028d2d48 ...
this code prints:
POST https://api.vk.com/method/wall.get
body: "owner_id=-17076618&offset=0&count=1"
it means that PostArray loaded first element in order to find out total count of elements. So:
post_array.count
=> 901
###Loading elements with index number
The code
post_array[0] => #<Hashie::Mash comments=#<Hashie::Mash count=0> date=1385007153 from_id=79826777 id...
prints
POST https://api.vk.com/method/wall.get
body: "owner_id=-17076618&offset=0&count=1"
and returns one post object.
###Loading elements with range
The code
post_array[10..20] => [#<Hashie::Mash comments=#<Hashie::Mash count=7> date=1384009402 from_id=6355...
prints
POST https://api.vk.com/method/wall.get
body: "owner_id=-17076618&offset=10&count=11"
and returns an array that contains 11 post objects.
###Accessing elements
Once you loaded element or elements they are saved within PostArray. So you can simply access them without loading. Another words the are cached within your MagicArray descendant instance.
If you want to see original Array of loaded elements:
post_array.elements => [#<Hashie::Mash comments=#<Hashie::Mash count=0> date=1385007153 from_id=7982...
And now you have got the Array. Lets check it:
post_array[0] => #<Hashie::Mash comments=#<Hashie::Mash count=0> date=1385007153 from_id=79826777 id...
post_array[1] => nil
Contributing
- Fork it
- Create your feature branch (
git checkout -b my-new-feature
) - Commit your changes (
git commit -am 'Add some feature'
) - Push to the branch (
git push origin my-new-feature
) - Create new Pull Request