magic_array 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +18 -0
- data/.rspec +2 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +142 -0
- data/Rakefile +1 -0
- data/lib/magic_array.rb +71 -0
- data/lib/magic_array/version.rb +1 -0
- data/magic_array.gemspec +24 -0
- data/spec/random_array.rb +23 -0
- data/spec/random_array_spec.rb +33 -0
- data/spec/spec_helper.rb +6 -0
- metadata +101 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: f35afb97d04e18fce3239d92699335d9467d7b07
|
4
|
+
data.tar.gz: 70ccfd6a4153e812419a9eada4957e775c9153d4
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 104b44209b802b7679e85ff47ff115463c979faa8a029743e1578a9668dbbf6ace2ee0bfccca54fdd80c269699623a2dd92171962549e3b4b5fca4fc0668cb48
|
7
|
+
data.tar.gz: 4e032900659eb9fb6f61445cbd302975de33990bc2c0c80d75f4e59918b0cca121cc05b9d17c05834d1561f72f050af7b31e152a90f313a6199a6863036dd33f
|
data/.gitignore
ADDED
data/.rspec
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2013 Alexander Panasyuk
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,142 @@
|
|
1
|
+
# MagicArray
|
2
|
+
|
3
|
+
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.
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Add this line to your application's Gemfile:
|
8
|
+
|
9
|
+
gem 'magic_array'
|
10
|
+
|
11
|
+
And then execute:
|
12
|
+
|
13
|
+
$ bundle
|
14
|
+
|
15
|
+
Or install it yourself as:
|
16
|
+
|
17
|
+
$ gem install magic_array
|
18
|
+
|
19
|
+
## Usage
|
20
|
+
|
21
|
+
Say you want to load some posts from vk.com. You can simply create the MagicArray descendant in order to load them.
|
22
|
+
You should always remember that you have to define **element_source(index)** and **elements_source(range_start, count)** using MagicArray.
|
23
|
+
|
24
|
+
**MagicArray descendant example:**
|
25
|
+
```ruby
|
26
|
+
class PostArray < MagicArray
|
27
|
+
|
28
|
+
load_limit 100
|
29
|
+
|
30
|
+
def initialize group_id
|
31
|
+
@group_id = "-#{group_id}"
|
32
|
+
self.count = vk.wall.get(owner_id: @group_id, offset: 0, count: 1).first
|
33
|
+
super
|
34
|
+
end
|
35
|
+
|
36
|
+
def element_source index
|
37
|
+
vk.wall.get(owner_id: @group_id, offset: index, count: 1).last
|
38
|
+
end
|
39
|
+
|
40
|
+
def elements_source range_start, range_count
|
41
|
+
result = vk.wall.get(owner_id: @group_id, offset: range_start, count: range_count)
|
42
|
+
result.shift
|
43
|
+
result
|
44
|
+
end
|
45
|
+
|
46
|
+
def vk
|
47
|
+
vk_source = -> {VK::Client.new}
|
48
|
+
@vk ||= vk_source.call
|
49
|
+
end
|
50
|
+
|
51
|
+
def search from, till
|
52
|
+
from_index = (bsearch{ |post| post.date <= from }) - 1
|
53
|
+
till_index = bsearch{ |post| post.date <= till }
|
54
|
+
self[till_index..from_index]
|
55
|
+
end
|
56
|
+
|
57
|
+
private
|
58
|
+
|
59
|
+
def bsearch &block
|
60
|
+
first = 0
|
61
|
+
last = count-1
|
62
|
+
mid = first + (last - first) / 2
|
63
|
+
while first<last
|
64
|
+
if yield(self[mid])
|
65
|
+
last = mid
|
66
|
+
else
|
67
|
+
first = mid + 1
|
68
|
+
end
|
69
|
+
mid = first + (last - first) / 2
|
70
|
+
end
|
71
|
+
if yield(self[last])
|
72
|
+
last
|
73
|
+
else
|
74
|
+
nil
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
end
|
79
|
+
```
|
80
|
+
|
81
|
+
###Initializing object
|
82
|
+
```ruby
|
83
|
+
post_array = PostArray.new 1234567
|
84
|
+
=> #<PostArray:0x000000028d3568 @group_id="-17076618", @vk=#<VkontakteApi::Client:0x000000028d2d48 ...
|
85
|
+
```
|
86
|
+
this code prints:
|
87
|
+
```
|
88
|
+
POST https://api.vk.com/method/wall.get
|
89
|
+
body: "owner_id=-17076618&offset=0&count=1"
|
90
|
+
```
|
91
|
+
it means that PostArray loaded first element in order to find out total count of elements. So:
|
92
|
+
```ruby
|
93
|
+
post_array.count
|
94
|
+
=> 901
|
95
|
+
```
|
96
|
+
|
97
|
+
###Loading elements with index number
|
98
|
+
The code
|
99
|
+
```ruby
|
100
|
+
post_array[0] => #<Hashie::Mash comments=#<Hashie::Mash count=0> date=1385007153 from_id=79826777 id...
|
101
|
+
```
|
102
|
+
prints
|
103
|
+
```
|
104
|
+
POST https://api.vk.com/method/wall.get
|
105
|
+
body: "owner_id=-17076618&offset=0&count=1"
|
106
|
+
```
|
107
|
+
and returns one post object.
|
108
|
+
|
109
|
+
###Loading elements with range
|
110
|
+
The code
|
111
|
+
```ruby
|
112
|
+
post_array[10..20] => [#<Hashie::Mash comments=#<Hashie::Mash count=7> date=1384009402 from_id=6355...
|
113
|
+
```
|
114
|
+
prints
|
115
|
+
```
|
116
|
+
POST https://api.vk.com/method/wall.get
|
117
|
+
body: "owner_id=-17076618&offset=10&count=11"
|
118
|
+
```
|
119
|
+
and returns an array that contains 11 post objects.
|
120
|
+
|
121
|
+
###Accessing elements
|
122
|
+
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.
|
123
|
+
If you want to see original Array of loaded elements:
|
124
|
+
|
125
|
+
```ruby
|
126
|
+
post_array.elements => [#<Hashie::Mash comments=#<Hashie::Mash count=0> date=1385007153 from_id=7982...
|
127
|
+
|
128
|
+
```
|
129
|
+
And now you have got the Array. Lets check it:
|
130
|
+
|
131
|
+
```ruby
|
132
|
+
post_array[0] => #<Hashie::Mash comments=#<Hashie::Mash count=0> date=1385007153 from_id=79826777 id...
|
133
|
+
post_array[1] => nil
|
134
|
+
```
|
135
|
+
|
136
|
+
## Contributing
|
137
|
+
|
138
|
+
1. Fork it
|
139
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
140
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
141
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
142
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
data/lib/magic_array.rb
ADDED
@@ -0,0 +1,71 @@
|
|
1
|
+
require "magic_array/version"
|
2
|
+
|
3
|
+
class MagicArray
|
4
|
+
|
5
|
+
attr_accessor :elements, :count
|
6
|
+
|
7
|
+
def initialize *attrs
|
8
|
+
@elements = []
|
9
|
+
@count = 0 unless @count
|
10
|
+
self
|
11
|
+
end
|
12
|
+
|
13
|
+
def method_missing m, *args, &block
|
14
|
+
@elements.public_send m, args
|
15
|
+
end
|
16
|
+
|
17
|
+
def [] index
|
18
|
+
case index
|
19
|
+
when Range then
|
20
|
+
if elements[index].empty? || elements[index].include?(nil)
|
21
|
+
load_elements(index)
|
22
|
+
else
|
23
|
+
elements[index]
|
24
|
+
end
|
25
|
+
else
|
26
|
+
elements[index] || load_element(index)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def all
|
31
|
+
self[0..(count-1)]
|
32
|
+
end
|
33
|
+
|
34
|
+
def load_element index
|
35
|
+
elements[index] = element_source index
|
36
|
+
end
|
37
|
+
|
38
|
+
def load_elements range
|
39
|
+
iterative_range = if range.end < count || count == 0
|
40
|
+
range.dup
|
41
|
+
else
|
42
|
+
Range.new range.begin, count-1
|
43
|
+
end
|
44
|
+
|
45
|
+
while iterative_range.count > 0
|
46
|
+
limited_range = iterative_range.first(@@load_limit)
|
47
|
+
iterative_range = Range.new(
|
48
|
+
(
|
49
|
+
limited_range.count < @@load_limit ?
|
50
|
+
iterative_range.end+1 :
|
51
|
+
iterative_range.begin+@@load_limit
|
52
|
+
),
|
53
|
+
iterative_range.end
|
54
|
+
)
|
55
|
+
array = elements_source limited_range.first, limited_range.count
|
56
|
+
limited_range.each_with_index do |element, index|
|
57
|
+
elements[element] = array[index]
|
58
|
+
end
|
59
|
+
end
|
60
|
+
elements[range]
|
61
|
+
end
|
62
|
+
|
63
|
+
class << self
|
64
|
+
|
65
|
+
def load_limit attr=nil
|
66
|
+
@@load_limit = attr || 100
|
67
|
+
end
|
68
|
+
|
69
|
+
end
|
70
|
+
|
71
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
MAGIC_ARRAY_VERSION = "0.1.1"
|
data/magic_array.gemspec
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'magic_array/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "magic_array"
|
8
|
+
spec.version = MAGIC_ARRAY_VERSION
|
9
|
+
spec.authors = ["Alexander Panasyuk"]
|
10
|
+
spec.email = ["panasmeister@gmail.com"]
|
11
|
+
spec.description = %q{Array that allows you to load data from specified source idly}
|
12
|
+
spec.summary = %q{Lasy loading array}
|
13
|
+
spec.homepage = "https://github.com/panasyuk/magic_array"
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
spec.files = `git ls-files`.split($/)
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
|
21
|
+
spec.add_development_dependency "bundler", "~> 1.3"
|
22
|
+
spec.add_development_dependency "rspec"
|
23
|
+
spec.add_development_dependency "rake"
|
24
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'magic_array'
|
2
|
+
|
3
|
+
class RandomArray < MagicArray
|
4
|
+
|
5
|
+
load_limit 100
|
6
|
+
|
7
|
+
def initialize
|
8
|
+
super
|
9
|
+
end
|
10
|
+
|
11
|
+
def element_source index
|
12
|
+
rand index
|
13
|
+
end
|
14
|
+
|
15
|
+
def elements_source range_start, range_count
|
16
|
+
result = []
|
17
|
+
range_count.times do |index|
|
18
|
+
result << rand(range_start+index)
|
19
|
+
end
|
20
|
+
result
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'random_array'
|
3
|
+
|
4
|
+
describe RandomArray do
|
5
|
+
|
6
|
+
let(:random_array){ RandomArray.new }
|
7
|
+
|
8
|
+
it 'should be descendant of MagicArray' do
|
9
|
+
RandomArray.ancestors.should include(MagicArray)
|
10
|
+
end
|
11
|
+
|
12
|
+
context 'on init' do
|
13
|
+
it 'should not contain elements' do
|
14
|
+
random_array.count.should == 0
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
it 'should generate element in range of its index when it is requested' do
|
19
|
+
random_array[0].should < 1
|
20
|
+
random_array[1].should == 0
|
21
|
+
random_array[2].should < 2
|
22
|
+
random_array[10].should < 10
|
23
|
+
end
|
24
|
+
|
25
|
+
it 'should generate array in requested range' do
|
26
|
+
result_array = random_array[50..60]
|
27
|
+
result_array.class.should be Array
|
28
|
+
result_array.each_with_index do |element, index|
|
29
|
+
element.should < 50+index
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
data/spec/spec_helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,101 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: magic_array
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Alexander Panasyuk
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2013-11-23 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ~>
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.3'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ~>
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.3'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rspec
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - '>='
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - '>='
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rake
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - '>='
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - '>='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
description: Array that allows you to load data from specified source idly
|
56
|
+
email:
|
57
|
+
- panasmeister@gmail.com
|
58
|
+
executables: []
|
59
|
+
extensions: []
|
60
|
+
extra_rdoc_files: []
|
61
|
+
files:
|
62
|
+
- .gitignore
|
63
|
+
- .rspec
|
64
|
+
- Gemfile
|
65
|
+
- LICENSE.txt
|
66
|
+
- README.md
|
67
|
+
- Rakefile
|
68
|
+
- lib/magic_array.rb
|
69
|
+
- lib/magic_array/version.rb
|
70
|
+
- magic_array.gemspec
|
71
|
+
- spec/random_array.rb
|
72
|
+
- spec/random_array_spec.rb
|
73
|
+
- spec/spec_helper.rb
|
74
|
+
homepage: https://github.com/panasyuk/magic_array
|
75
|
+
licenses:
|
76
|
+
- MIT
|
77
|
+
metadata: {}
|
78
|
+
post_install_message:
|
79
|
+
rdoc_options: []
|
80
|
+
require_paths:
|
81
|
+
- lib
|
82
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
83
|
+
requirements:
|
84
|
+
- - '>='
|
85
|
+
- !ruby/object:Gem::Version
|
86
|
+
version: '0'
|
87
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
88
|
+
requirements:
|
89
|
+
- - '>='
|
90
|
+
- !ruby/object:Gem::Version
|
91
|
+
version: '0'
|
92
|
+
requirements: []
|
93
|
+
rubyforge_project:
|
94
|
+
rubygems_version: 2.0.3
|
95
|
+
signing_key:
|
96
|
+
specification_version: 4
|
97
|
+
summary: Lasy loading array
|
98
|
+
test_files:
|
99
|
+
- spec/random_array.rb
|
100
|
+
- spec/random_array_spec.rb
|
101
|
+
- spec/spec_helper.rb
|