pipeliner 1.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/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