pipeliner 1.0 → 1.1

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG CHANGED
@@ -0,0 +1,4 @@
1
+ 1.1
2
+ * Modified Pipeline#hook to allow conditional matching
3
+ 1.0
4
+ * Initial release
data/README.rdoc CHANGED
@@ -34,7 +34,7 @@ In the example above, we use a simple block to process any String type objects.
34
34
 
35
35
  require 'pipeliner'
36
36
 
37
- class Tester < Pipeliner::Filter
37
+ class Tester
38
38
  attr_reader :store
39
39
  def initialize
40
40
  @store = []
@@ -54,6 +54,31 @@ In the example above, we use a simple block to process any String type objects.
54
54
 
55
55
  => ["String", 100, {:test=>:data}]
56
56
 
57
+ Another handy thing is limiting what hooks are called when a very generic type is hooked. When supplying an object method to call, we can also pass a block that provides the condition for which the hook will be run:
58
+
59
+ require 'pipeliner'
60
+
61
+ class Tester
62
+ attr_reader :store
63
+ def initialize
64
+ @store = []
65
+ end
66
+ def process(m)
67
+ @store << m
68
+ end
69
+ end
70
+
71
+ pipeline = Pipeliner::Pipeline.new
72
+ obj = Tester.new
73
+ pipeline.hook(Object, obj, :process){|o| o.is_a?(String) }
74
+ pipeline << "String"
75
+ pipeline << 100
76
+ pipeline << {:test => :data}
77
+ p obj.store
78
+
79
+ => ["String"]
80
+
81
+
57
82
  But, what if you want anything added to the pipeline to be modified before it is distributed out to hooked processors? Well, then you would use a filter:
58
83
 
59
84
  require 'pipeliner'
data/Rakefile ADDED
@@ -0,0 +1,54 @@
1
+ #
2
+ # To change this template, choose Tools | Templates
3
+ # and open the template in the editor.
4
+
5
+
6
+ require 'rubygems'
7
+ require 'rake'
8
+ require 'rake/clean'
9
+ require 'rake/gempackagetask'
10
+ require 'rake/rdoctask'
11
+ require 'rake/testtask'
12
+ require 'spec/rake/spectask'
13
+
14
+ spec = Gem::Specification.new do |s|
15
+ s.name = 'pipeliner'
16
+ s.author = 'spox'
17
+ s.email = 'spox@modspox.com'
18
+ s.version = '1.1'
19
+ s.summary = 'Object Pipeline'
20
+ s.platform = Gem::Platform::RUBY
21
+ s.files = Dir['**/*']
22
+ s.rdoc_options = %w(--title pipeliner --main README.rdoc --line-numbers)
23
+ s.extra_rdoc_files = %w(README.rdoc CHANGELOG)
24
+ s.require_paths = %w(lib)
25
+ s.required_ruby_version = '>= 1.8.6'
26
+ s.add_dependency 'actionpool', '~> 0.2.3'
27
+ s.add_dependency 'splib', '~> 1.4.3'
28
+ s.homepage = %q(http://github.com/spox/pipeliner)
29
+ s.description = "Simple library to allow pipeline styled communications between objects"
30
+ end
31
+
32
+ Rake::GemPackageTask.new(spec) do |p|
33
+ p.gem_spec = spec
34
+ p.need_tar = true
35
+ p.need_zip = true
36
+ end
37
+
38
+ Rake::RDocTask.new do |rdoc|
39
+ files =['README', 'LICENSE', 'lib/**/*.rb']
40
+ rdoc.rdoc_files.add(files)
41
+ rdoc.main = "README" # page to start on
42
+ rdoc.title = "pipeliner Docs"
43
+ rdoc.rdoc_dir = 'doc/rdoc' # rdoc output folder
44
+ rdoc.options << '--line-numbers'
45
+ end
46
+
47
+ Rake::TestTask.new do |t|
48
+ t.test_files = FileList['test/**/*.rb']
49
+ end
50
+
51
+ Spec::Rake::SpecTask.new do |t|
52
+ t.spec_files = FileList['spec/**/*.rb']
53
+ t.libs << Dir["lib"]
54
+ end
@@ -1,4 +1,6 @@
1
- ['thread', 'splib', 'actionpool', 'pipeliner/FilterManager'].each{|f| require f}
1
+ require 'actionpool'
2
+ require 'splib'
3
+ require 'pipeliner/FilterManager'
2
4
 
3
5
  Splib.load :Constants
4
6
 
@@ -13,17 +15,21 @@ module Pipeliner
13
15
  @hooks = {}
14
16
  @lock = Mutex.new
15
17
  @filters = args[:filters] ? args[:filters] : FilterManager.new
18
+ if(!args[:pool])
19
+ Kernel.at_exit do
20
+ close
21
+ end
22
+ end
16
23
  end
17
24
 
18
25
  # Close the pipeline
19
- # Note: This is important to at the end of a script when not
26
+ # Note: This is important to call at the end of a script when not
20
27
  # providing an ActionPool thread pool to the pipeline.
21
28
  # This will ensure the thread pool is properly shutdown
22
29
  # and avoid the script hanging.
23
30
  def close
24
31
  @pool.shutdown
25
32
  clear
26
- @pool = nil
27
33
  end
28
34
 
29
35
  # Open the pipeline
@@ -46,25 +52,38 @@ module Pipeliner
46
52
  # type:: Type of Objects to pass to object
47
53
  # object:: Object to hook to pipeline
48
54
  # method:: Method to call on object
49
- # block:: Block to apply to object (called without object and method set)
50
- # Hooks an Object into the pipeline for objects of a given type
55
+ # block:: Block to apply to object (called without object and method set) or conditional
56
+ # Hooks an Object into the pipeline for objects of a given type. The block can serve
57
+ # two purposes here. First, we can hook a block to a type like so:
58
+ # pipeline.hook(String){|s| puts s }
59
+ # Or, we can use the block as a conditional for calling an object's method:
60
+ # pipeline.hook(String, obj, :method){|s| s == 'test' }
61
+ # In the second example, this hook will only be called if the String type object
62
+ # matches the conditional in the block, meaning the string must be 'test'
51
63
  def hook(type, object=nil, method=nil, &block)
52
- raise ArgumentError.new('No object information or block provided for hook') if !block_given? && object.nil? && method.nil?
53
- raise ArgumentError.new('Block must accept a parameter') unless block.nil? || block.arity == 1 || block.arity < 0
64
+ raise ArgumentError.new 'Type must be provided' if type.nil?
65
+ if(block && (block.arity > 1 || block.arity == 0))
66
+ raise ArgumentError.new('Block must accept a parameter')
67
+ end
68
+ if((object && method.nil?) || (object.nil? && method))
69
+ raise ArgumentError.new('Object AND method must be provided')
70
+ end
71
+ if(!block_given? && object.nil? && method.nil?)
72
+ raise ArgumentError.new('No object information or block provided for hook')
73
+ end
54
74
  @lock.synchronize do
55
75
  const = Splib.find_const(type)
56
76
  type = const unless const.nil?
57
77
  @hooks[type] ||= {}
58
- if(block_given?)
78
+ if(block_given? && object.nil? && method.nil?)
59
79
  @hooks[type][:procs] ||= []
60
80
  @hooks[type][:procs] << block
61
- end
62
- if(object && method)
81
+ else
63
82
  name = object.class
64
83
  method = method.to_sym
65
84
  raise ArgumentError.new('Given object does not respond to given method') unless object.respond_to?(method)
66
85
  @hooks[type][name] ||= []
67
- @hooks[type][name] << {:object => object, :method => method}
86
+ @hooks[type][name] << {:object => object, :method => method, :req => !block_given? ? lambda{|x|true} : block}
68
87
  end
69
88
  end
70
89
  block_given? ? block : nil
@@ -144,7 +163,7 @@ module Pipeliner
144
163
  if(key == :procs)
145
164
  objects.each{|pr| @pool.process{ pr.call(o) }}
146
165
  else
147
- objects.each{|h| @pool.process{ h[:object].send(h[:method], o)}}
166
+ objects.each{|h| @pool.process{ h[:object].send(h[:method], o) if h[:req].call(o) }}
148
167
  end
149
168
  end
150
169
  end
@@ -0,0 +1,7 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <project-private xmlns="http://www.netbeans.org/ns/project-private/1">
3
+ <editor-bookmarks xmlns="http://www.netbeans.org/ns/editor-bookmarks/1"/>
4
+ <open-files xmlns="http://www.netbeans.org/ns/projectui-open-files/1">
5
+ <file>file:/home/spox/NetBeansProjects/pipeliner/lib/pipeliner/Pipeline.rb</file>
6
+ </open-files>
7
+ </project-private>
@@ -0,0 +1,19 @@
1
+ clean=Remove any temporary products.
2
+ clobber=Remove any generated file.
3
+ clobber_package=Remove package products
4
+ clobber_rdoc=Remove rdoc products
5
+ doc=
6
+ doc/rdoc=
7
+ doc/rdoc/index.html=
8
+ gem=Build the gem file pipeliner-1.1.gem
9
+ package=Build all the packages
10
+ pkg=
11
+ pkg/pipeliner-1.1=
12
+ pkg/pipeliner-1.1.gem=
13
+ pkg/pipeliner-1.1.tgz=
14
+ pkg/pipeliner-1.1.zip=
15
+ rdoc=Build the rdoc HTML Files
16
+ repackage=Force a rebuild of the package files
17
+ rerdoc=Force a rebuild of the RDOC files
18
+ spec=Run specs
19
+ test=Run tests
@@ -0,0 +1,6 @@
1
+ main.file=
2
+ platform.active=default
3
+ source.encoding=UTF-8
4
+ spec.src.dir=spec
5
+ src.dir=lib
6
+ test.src.dir=test
@@ -0,0 +1,16 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <project xmlns="http://www.netbeans.org/ns/project/1">
3
+ <type>org.netbeans.modules.ruby.rubyproject</type>
4
+ <configuration>
5
+ <data xmlns="http://www.netbeans.org/ns/ruby-project/1">
6
+ <name>pipeliner</name>
7
+ <source-roots>
8
+ <root id="src.dir"/>
9
+ </source-roots>
10
+ <test-roots>
11
+ <root id="test.src.dir"/>
12
+ <root id="spec.src.dir"/>
13
+ </test-roots>
14
+ </data>
15
+ </configuration>
16
+ </project>
data/pipeliner.gemspec CHANGED
@@ -2,7 +2,7 @@ spec = Gem::Specification.new do |s|
2
2
  s.name = 'pipeliner'
3
3
  s.author = 'spox'
4
4
  s.email = 'spox@modspox.com'
5
- s.version = '1.0'
5
+ s.version = '1.1'
6
6
  s.summary = 'Object Pipeline'
7
7
  s.platform = Gem::Platform::RUBY
8
8
  s.files = Dir['**/*']
@@ -10,8 +10,8 @@ spec = Gem::Specification.new do |s|
10
10
  s.extra_rdoc_files = %w(README.rdoc CHANGELOG)
11
11
  s.require_paths = %w(lib)
12
12
  s.required_ruby_version = '>= 1.8.6'
13
- s.add_dependency 'ActionPool', '~> 0.2.0'
14
- s.add_dependency 'splib', '~> 1.1'
13
+ s.add_dependency 'actionpool', '~> 0.2.3'
14
+ s.add_dependency 'splib', '~> 1.4.3'
15
15
  s.homepage = %q(http://github.com/spox/pipeliner)
16
16
  s.description = "Simple library to allow pipeline styled communications between objects"
17
17
  end
data/spec/dummy.rb ADDED
File without changes
File without changes
File without changes
@@ -32,7 +32,7 @@ class PipelineTest < Test::Unit::TestCase
32
32
  end
33
33
  def test_hook_addition
34
34
  assert_raise(ArgumentError){ @pipeline.hook(String) }
35
- assert_raise(ArgumentError){ @pipeline.hook(String){ true } }
35
+ assert_raise(ArgumentError){ @pipeline.hook(String){ true } } if RUBY_VERSION >= '1.9.0'
36
36
  assert_raise(ArgumentError){ @pipeline.hook(String){|a,b| true} }
37
37
  assert_kind_of(Proc, @pipeline.hook(String){|a| true })
38
38
  assert_kind_of(Proc, @pipeline.hook(String){|a, *b| true })
@@ -70,6 +70,20 @@ class PipelineTest < Test::Unit::TestCase
70
70
  @pipeline.clear
71
71
  assert(@pipeline.hooks.empty?)
72
72
  end
73
+ def test_hook_conditional
74
+ obj = Tester.new
75
+ @pipeline.hook(String, obj, :method)
76
+ @pipeline << "test"
77
+ sleep(0.01)
78
+ assert_equal(1, obj.messages.size)
79
+ @pipeline.hook(String, obj, :method){|s| s == 'test' }
80
+ @pipeline << "fubar"
81
+ sleep(0.01)
82
+ assert_equal(2, obj.messages.size)
83
+ @pipeline << "test"
84
+ sleep(0.01)
85
+ assert_equal(4, obj.messages.size)
86
+ end
73
87
  def test_flush
74
88
  out = []
75
89
  assert(out.empty?)
@@ -100,6 +114,7 @@ class PipelineTest < Test::Unit::TestCase
100
114
  @pipeline.filters.add(String){|s|10}
101
115
  @pipeline.hook(Object){|s|out << s}
102
116
  @pipeline << 'fubar'
117
+ sleep(0.01)
103
118
  assert(out.include?(10))
104
119
  assert(!out.include?('fubar'))
105
120
  @pipeline.filters.clear
File without changes
metadata CHANGED
@@ -1,7 +1,11 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pipeliner
3
3
  version: !ruby/object:Gem::Version
4
- version: "1.0"
4
+ prerelease: false
5
+ segments:
6
+ - 1
7
+ - 1
8
+ version: "1.1"
5
9
  platform: ruby
6
10
  authors:
7
11
  - spox
@@ -9,29 +13,37 @@ autorequire:
9
13
  bindir: bin
10
14
  cert_chain: []
11
15
 
12
- date: 2009-12-30 00:00:00 -08:00
16
+ date: 2010-04-20 00:00:00 -07:00
13
17
  default_executable:
14
18
  dependencies:
15
19
  - !ruby/object:Gem::Dependency
16
- name: ActionPool
17
- type: :runtime
18
- version_requirement:
19
- version_requirements: !ruby/object:Gem::Requirement
20
+ name: actionpool
21
+ prerelease: false
22
+ requirement: &id001 !ruby/object:Gem::Requirement
20
23
  requirements:
21
24
  - - ~>
22
25
  - !ruby/object:Gem::Version
23
- version: 0.2.0
24
- version:
26
+ segments:
27
+ - 0
28
+ - 2
29
+ - 3
30
+ version: 0.2.3
31
+ type: :runtime
32
+ version_requirements: *id001
25
33
  - !ruby/object:Gem::Dependency
26
34
  name: splib
27
- type: :runtime
28
- version_requirement:
29
- version_requirements: !ruby/object:Gem::Requirement
35
+ prerelease: false
36
+ requirement: &id002 !ruby/object:Gem::Requirement
30
37
  requirements:
31
38
  - - ~>
32
39
  - !ruby/object:Gem::Version
33
- version: "1.1"
34
- version:
40
+ segments:
41
+ - 1
42
+ - 4
43
+ - 3
44
+ version: 1.4.3
45
+ type: :runtime
46
+ version_requirements: *id002
35
47
  description: Simple library to allow pipeline styled communications between objects
36
48
  email: spox@modspox.com
37
49
  executables: []
@@ -42,14 +54,20 @@ extra_rdoc_files:
42
54
  - README.rdoc
43
55
  - CHANGELOG
44
56
  files:
45
- - tests/cases/Filter.rb
46
- - tests/cases/FilterManager.rb
47
- - tests/cases/Pipeline.rb
48
- - tests/run_tests.rb
57
+ - spec/dummy.rb
58
+ - test/cases/Filter.rb
59
+ - test/cases/FilterManager.rb
60
+ - test/cases/Pipeline.rb
61
+ - test/run_tests.rb
62
+ - nbproject/private/rake-d.txt
63
+ - nbproject/private/private.xml
64
+ - nbproject/project.xml
65
+ - nbproject/project.properties
49
66
  - lib/pipeliner/Filter.rb
50
67
  - lib/pipeliner/FilterManager.rb
51
68
  - lib/pipeliner/Pipeline.rb
52
69
  - lib/pipeliner.rb
70
+ - Rakefile
53
71
  - CHANGELOG
54
72
  - LICENSE
55
73
  - README.rdoc
@@ -71,18 +89,22 @@ required_ruby_version: !ruby/object:Gem::Requirement
71
89
  requirements:
72
90
  - - ">="
73
91
  - !ruby/object:Gem::Version
92
+ segments:
93
+ - 1
94
+ - 8
95
+ - 6
74
96
  version: 1.8.6
75
- version:
76
97
  required_rubygems_version: !ruby/object:Gem::Requirement
77
98
  requirements:
78
99
  - - ">="
79
100
  - !ruby/object:Gem::Version
101
+ segments:
102
+ - 0
80
103
  version: "0"
81
- version:
82
104
  requirements: []
83
105
 
84
106
  rubyforge_project:
85
- rubygems_version: 1.3.5
107
+ rubygems_version: 1.3.6
86
108
  signing_key:
87
109
  specification_version: 3
88
110
  summary: Object Pipeline