dunder 0.1.0 → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/Rakefile CHANGED
@@ -16,7 +16,13 @@ Jeweler::Tasks.new do |gem|
16
16
  gem.homepage = "http://github.com/Fonsan/dunder"
17
17
  gem.license = "MIT"
18
18
  gem.summary = %Q{A simple way of doing heavy work in a background process and when you really need the object it will block until it is done}
19
- gem.description = %Q{A simple way of doing heavy work in a background process and when you really need the object it will block until it is done}
19
+ gem.description = %Q{For tasks that can be started early and evaluated late.
20
+
21
+ Typically one might want start multiple heavy tasks concurrent.
22
+ This is already solvable with threads or the [reactor-pattern](http://rubyeventmachine.com/) but setting this up could be cumbersome or require direct interactions with threads ex.
23
+
24
+ Dunder is a simple way of abstracting this:
25
+ you simply pass a block to Dunder.load with the expected class as the argument}
20
26
  gem.email = "fonsan@gmail.com"
21
27
  gem.authors = ["Fonsan"]
22
28
  # Include your dependencies below. Runtime dependencies are required when using your gem,
data/Readme.md CHANGED
@@ -5,19 +5,88 @@ Heavily inspired by Adam Sandersons [post](http://endofline.wordpress.com/2011/0
5
5
 
6
6
  Dunder
7
7
  =========================
8
+ For tasks that can be started early and evaluated late.
8
9
 
10
+ Typically one might want start multiple heavy tasks concurrent.
11
+ This is already solvable with threads or the [reactor-pattern](http://rubyeventmachine.com/) but setting this up could be cumbersome or require direct interactions with threads ex.
12
+
13
+ Dunder is a simple way of abstracting this:
14
+ you simply pass a block to Dunder.load with the expected class as the argument
9
15
 
10
16
  Usage
11
- =====
12
- lazy_bar = LazyLoad.load(String) {
17
+
18
+ lazy_foo = Dunder.load(String) {
13
19
  # Simulate heavy IO
14
20
  sleep 2
15
21
  "bar"
16
22
  }
23
+
24
+
25
+ lazy_b = Dunder.load(String) {
26
+ # Simulate heavy IO
27
+ sleep 2
28
+ "bar"
29
+ }
30
+
17
31
  puts lazy_bar
32
+ puts lazy_foo
33
+ # Will finish after 2 seconds
34
+
35
+ worth mentioning is that if you access the variable in someway before that it will block earlier
36
+ ex
37
+ lazy_array = Dunder.load(Array) do
38
+ sleep 1
39
+ [1,2,3]
40
+ end
41
+ puts lazy_array.length # <- will block here until the above sleep is done
42
+ sleep 1 # other heavy stuff
43
+ puts lazy_array # <- will be printed after 2 seconds
44
+
45
+ changing the order will fix this though
46
+
47
+ lazy_array = Dunder.load(Array) do
48
+ sleep 1
49
+ [1,2,3]
50
+ end
51
+ sleep 1 # other heavy stuff
52
+ puts lazy_array.length # <- will block here until the above sleep in the block is done
53
+ puts lazy_array # <- will be printed after 1 second
54
+
55
+ API
56
+ Dunder.load(Klass,instance = nil) {
57
+ #things to do
58
+ value
59
+ }
60
+ Klass must be the class of value
61
+ instance, During the process Dunder will call Klass.new if your class has a mandatory argument in initialize (the constructor) you could create a dummy instance yourself or you could set the return type to Array and return [value] and then use Dunder.load(Array) do [value] end.first
62
+
63
+ Rails
64
+
65
+ @lazy_posts = Dunder.load(Array) do
66
+ Post.all
67
+ end
68
+ @lazy_users = Dunder.load(Array) do
69
+ User.all
70
+ end
71
+
72
+ and then later in views
73
+
74
+ <%= @lazyposts.each do %> <- this will block until the posts have been loaded
75
+ ...
76
+ <% end %>
77
+
78
+
79
+ Known problems
80
+
81
+ it works with most types but has only been tested with 1.9.2
82
+ Integer fails with
83
+ NotImplementedError: super from singleton method that is defined to multiple classes is not supported;
84
+ this will be fixed in 1.9.3 or later
85
+ Or a SystemStackError: stack level too deep
86
+
18
87
  Install
19
88
  =======
20
- gem install xxxx
89
+ gem install dunder
21
90
 
22
91
 
23
92
  (The MIT License)
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.1.0
1
+ 0.1.1
data/dunder.gemspec ADDED
@@ -0,0 +1,74 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = %q{dunder}
8
+ s.version = "0.1.1"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Fonsan"]
12
+ s.date = %q{2011-01-26}
13
+ s.description = %q{For tasks that can be started early and evaluated late.
14
+
15
+ Typically one might want start multiple heavy tasks concurrent.
16
+ This is already solvable with threads or the [reactor-pattern](http://rubyeventmachine.com/) but setting this up could be cumbersome or require direct interactions with threads ex.
17
+
18
+ Dunder is a simple way of abstracting this:
19
+ you simply pass a block to Dunder.load with the expected class as the argument}
20
+ s.email = %q{fonsan@gmail.com}
21
+ s.extra_rdoc_files = [
22
+ "LICENSE.txt"
23
+ ]
24
+ s.files = [
25
+ "Gemfile",
26
+ "Gemfile.lock",
27
+ "LICENSE.txt",
28
+ "Rakefile",
29
+ "Readme.md",
30
+ "VERSION",
31
+ "dunder.gemspec",
32
+ "lib/dunder.rb",
33
+ "test/helper.rb",
34
+ "test/test_dunder.rb"
35
+ ]
36
+ s.homepage = %q{http://github.com/Fonsan/dunder}
37
+ s.licenses = ["MIT"]
38
+ s.require_paths = ["lib"]
39
+ s.rubygems_version = %q{1.3.7}
40
+ s.summary = %q{A simple way of doing heavy work in a background process and when you really need the object it will block until it is done}
41
+ s.test_files = [
42
+ "test/helper.rb",
43
+ "test/test_dunder.rb"
44
+ ]
45
+
46
+ if s.respond_to? :specification_version then
47
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
48
+ s.specification_version = 3
49
+
50
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
51
+ s.add_runtime_dependency(%q<activesupport>, [">= 3.0.3"])
52
+ s.add_runtime_dependency(%q<activerecord>, [">= 3.0.3"])
53
+ s.add_development_dependency(%q<shoulda>, [">= 0"])
54
+ s.add_development_dependency(%q<bundler>, ["~> 1.0.0"])
55
+ s.add_development_dependency(%q<jeweler>, ["~> 1.5.2"])
56
+ s.add_development_dependency(%q<rcov>, [">= 0"])
57
+ else
58
+ s.add_dependency(%q<activesupport>, [">= 3.0.3"])
59
+ s.add_dependency(%q<activerecord>, [">= 3.0.3"])
60
+ s.add_dependency(%q<shoulda>, [">= 0"])
61
+ s.add_dependency(%q<bundler>, ["~> 1.0.0"])
62
+ s.add_dependency(%q<jeweler>, ["~> 1.5.2"])
63
+ s.add_dependency(%q<rcov>, [">= 0"])
64
+ end
65
+ else
66
+ s.add_dependency(%q<activesupport>, [">= 3.0.3"])
67
+ s.add_dependency(%q<activerecord>, [">= 3.0.3"])
68
+ s.add_dependency(%q<shoulda>, [">= 0"])
69
+ s.add_dependency(%q<bundler>, ["~> 1.0.0"])
70
+ s.add_dependency(%q<jeweler>, ["~> 1.5.2"])
71
+ s.add_dependency(%q<rcov>, [">= 0"])
72
+ end
73
+ end
74
+
data/lib/dunder.rb CHANGED
@@ -3,6 +3,7 @@ require 'delegate'
3
3
 
4
4
  class FutureArray < DelegateClass(Array )
5
5
  def initialize(&block)
6
+ super(Array.new)
6
7
  @_thread = Thread.start(&block)
7
8
  end
8
9
 
@@ -12,6 +13,7 @@ class FutureArray < DelegateClass(Array )
12
13
  end
13
14
  end
14
15
 
16
+
15
17
  class Dunder
16
18
 
17
19
  def self.create_lazy_class(klass,instance = nil)
@@ -26,16 +28,23 @@ class Dunder
26
28
  end
27
29
 
28
30
  def __getobj__
29
- __setobj__(@_thread.value) if @_thread.alive?
30
- super
31
+ result = @_thread.value
32
+ __setobj__(result) if @_thread.alive?
33
+
34
+ instance_eval do
35
+ def class
36
+ __getobj__.class
37
+ end
38
+ end
39
+ result
31
40
  end
41
+
32
42
  end
33
43
  instance ||= klass.new
34
-
35
44
  def c.lazy_instance
36
45
  instance
37
46
  end
38
-
47
+
39
48
  c
40
49
  end
41
50
 
@@ -65,20 +74,5 @@ class Dunder
65
74
  lazy_class.new(&block)
66
75
  end
67
76
  end
68
- =begin
69
77
 
70
- puts Dunder.load(String) {
71
- "hello"
72
- }
73
-
74
- puts Dunder.load(Integer) {
75
- 1
76
- }
77
-
78
- puts Dunder.load(String) {
79
- #Slow
80
- sleep 2
81
- "fubar"
82
- }
83
78
 
84
- =end
data/test/test_dunder.rb CHANGED
@@ -2,8 +2,15 @@ require 'helper'
2
2
 
3
3
  class TestDunder < Test::Unit::TestCase
4
4
  should "have some simple testing" do
5
- assert_equal "bar",Dunder.load(String) {
6
- "bar"
7
- }
5
+
6
+ b = "bar"
7
+
8
+ lazy_b = Dunder.load(String) {
9
+ "bar"
10
+ }
11
+
12
+ assert_equal b,lazy_b
13
+ puts lazy_b.class
14
+ assert_equal b.class, lazy_b.class
8
15
  end
9
16
  end
metadata CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
5
5
  segments:
6
6
  - 0
7
7
  - 1
8
- - 0
9
- version: 0.1.0
8
+ - 1
9
+ version: 0.1.1
10
10
  platform: ruby
11
11
  authors:
12
12
  - Fonsan
@@ -103,7 +103,14 @@ dependencies:
103
103
  type: :development
104
104
  prerelease: false
105
105
  version_requirements: *id006
106
- description: A simple way of doing heavy work in a background process and when you really need the object it will block until it is done
106
+ description: |-
107
+ For tasks that can be started early and evaluated late.
108
+
109
+ Typically one might want start multiple heavy tasks concurrent.
110
+ This is already solvable with threads or the [reactor-pattern](http://rubyeventmachine.com/) but setting this up could be cumbersome or require direct interactions with threads ex.
111
+
112
+ Dunder is a simple way of abstracting this:
113
+ you simply pass a block to Dunder.load with the expected class as the argument
107
114
  email: fonsan@gmail.com
108
115
  executables: []
109
116
 
@@ -118,6 +125,7 @@ files:
118
125
  - Rakefile
119
126
  - Readme.md
120
127
  - VERSION
128
+ - dunder.gemspec
121
129
  - lib/dunder.rb
122
130
  - test/helper.rb
123
131
  - test/test_dunder.rb
@@ -135,7 +143,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
135
143
  requirements:
136
144
  - - ">="
137
145
  - !ruby/object:Gem::Version
138
- hash: 621904010295938316
146
+ hash: 2997372027129916411
139
147
  segments:
140
148
  - 0
141
149
  version: "0"