multi_block 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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: a5e8f01ab709dd3be84548791a9b7b67e43bd350
4
+ data.tar.gz: 2137ce5ca59fb9fbdcd9eefc303998e1bda61071
5
+ SHA512:
6
+ metadata.gz: 38d32e968578403ca6f2bdf1e0dfde082d589a4d0d755b4e0febed43c61deec346521f5af7ad66f4d1504a87ac603781b6affcfea8b2d430e27dffa3155892fe
7
+ data.tar.gz: 6b75186f120a1008aeb5ade1aafb374264d8e046d7e64fa905e937b261c516f9325ad00a75e9457b818e09cfbf122b9e636783c4b4fe463a7f03dc9e6a0bf9a9
@@ -0,0 +1,17 @@
1
+ language: ruby
2
+
3
+ rvm:
4
+ - ruby-head
5
+ - 2.2.1
6
+ - 2.2.0
7
+ - 2.1.5
8
+ - 2.1.4
9
+ - 2.1.3
10
+ - 2.1.2
11
+ - 2.1.1
12
+ - 2.1.0
13
+ - 2.0.0
14
+ - rbx-2
15
+ - jruby-head
16
+ - jruby-9000
17
+
@@ -0,0 +1,6 @@
1
+ == 1.1.0 (master)
2
+ * Updates for 2015 Rubies, drop support for Ruby 1
3
+ * Simplify activating Array extension via: require 'multi_block/array'
4
+
5
+ == 1.0.0
6
+ * Initial Release
@@ -1,6 +1,6 @@
1
1
  The MIT LICENSE
2
2
 
3
- Copyright (c) 2011 Jan Lelis
3
+ Copyright (c) 2011, 2015 Jan Lelis
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining
6
6
  a copy of this software and associated documentation files (the
@@ -1,38 +1,19 @@
1
- = MultiBlock
1
+ = MultiBlock {<img src="https://badge.fury.io/rb/multi_block.svg" />}[http://badge.fury.io/rb/multi_block] {<img src="https://travis-ci.org/janlelis/multi_block.png" />}[https://travis-ci.org/janlelis/multi_block]
2
2
 
3
- MultiBlock is a mini framework for passing multiple blocks to methods. It uses "named procs" to accomplish this in a nice way. The receiving method can either yield all blocks, or just call specific ones, identified by order or name.
3
+ MultiBlock is a mini framework for passing multiple blocks to methods. It uses {named procs}[https://github.com/janlelis/named_proc] to accomplish this with a simple syntax. The receiving method can either yield all blocks, or just call specific ones, identified by order or name.
4
4
 
5
- These gem was build during a codebrawl contest. You might also take a look at the other entries: http://codebrawl.com/contests/methods-taking-multiple-blocks
6
5
 
7
6
  == Setup
8
7
 
9
- gem install multi_block
8
+ Add to Gemfile:
10
9
 
11
- == Named Procs
12
- A named proc acts like a normal proc, but has got a name attribute. You can create it by calling a method with the desired name on +proc+:
10
+ gem 'multi_block'
13
11
 
14
- >> a = proc.even?{ |e| e.even? }
15
- => #<NamedProc:0x00000001ffc340@(irb):1>
16
- >> a.name
17
- => :even?
18
- >> a[42]
19
- => false
20
12
 
21
- In the same way, you can create lambdas:
22
-
23
- >> b = lambda.doubler{ |e| e * 2 }
24
- => #<NamedProc:0x000000020685e0@(irb):7 (lambda)>
25
- >> b.name
26
- => :doubler
27
- >> b[21]
28
- => 42
29
- >> b.lambda?
30
- => true
31
-
32
- == MultiBlock Usage
13
+ == Usage
33
14
  === Defining methods that use multiple blocks
34
15
 
35
- The first argument given to yield always defines the desired block(s). The other arguments get directly passed to the block(s). So these are example calls to the block:
16
+ The first argument given to yield always defines the desired block(s). The other arguments get directly passed to the block(s):
36
17
 
37
18
  yield # calls all given procs without args
38
19
  yield :success # calls :success proc without args
@@ -43,26 +24,31 @@ The first argument given to yield always defines the desired block(s). The other
43
24
  yield success: "Code Brawl!", # calls each keyed proc,
44
25
  error: [500, "Internal Brawl Error"] # values are the args
45
26
 
27
+
28
+ === Calling methods with multiple blocks
29
+
46
30
  Consider these two example methods:
47
31
 
32
+ # calls the :success block if everything worked well
48
33
  def ajax
49
- yield rand(6) != 0 ? :success : :error # calls the :success block if everything worked well
34
+ yield rand(6) != 0 ? :success : :error
50
35
  end
51
36
 
37
+ # calls the n-th block
52
38
  def dice
53
39
  random_number = rand(6)
54
- yield random_number, random_number + 1 # calls the n-th block
40
+ yield random_number, random_number + 1
55
41
  end
56
42
 
57
- === Calling methods with multiple blocks
58
43
 
59
- It's done by calling the +blocks+ helper method:
44
+ Multiple blocks can be passed using +blocks+:
60
45
 
61
46
  ajax &blocks[
62
- proc.success do puts "Yeah!" end,
63
- proc.error do puts "Error..." end,
47
+ proc.success{ puts "Yeah!" },
48
+ proc.error { puts "Error..." },
64
49
  ]
65
50
 
51
+
66
52
  The dice method could, for example, be called in this way:
67
53
 
68
54
  dice &blocks[
@@ -74,22 +60,24 @@ The dice method could, for example, be called in this way:
74
60
  proc{ rand(42) != 0 ? ":)" : ":D"},
75
61
  ]
76
62
 
63
+
77
64
  == Bonus sugar: Array extension
78
65
 
79
- If you like the slim <tt>&to_proc</tt> operator, you can further optimize the syntax by calling:
66
+ If you like the slim <tt>&to_proc</tt> operator, you can further optimize the syntax by activating the core extension for array:
80
67
 
81
- Array.send :include, MultiBlock::Array
68
+ require 'multi_block/array'
82
69
 
83
- Now, it's getting real hot:
70
+ Now you do not need the +blocks+ helper anymore. Instead just do:
84
71
 
85
72
  do_something, some_argument, &[
86
- proc.easy_way do
73
+ proc.easy_way{
87
74
  # do it the easy way
88
- end,
89
-
90
- proc.complex_way do
75
+ },
76
+ proc.complex_way{
91
77
  # use complex heuristics, etc.
92
- end,
78
+ },
93
79
  ]
94
80
 
95
- == J-_-L
81
+
82
+ == MIT License
83
+ See the original gist: https://gist.github.com/4b2f5fd0b45118e46d0f
@@ -1,74 +1,6 @@
1
- # encoding: utf-8
2
1
  require 'named_proc'
3
2
 
4
- module MultiBlock
5
- # multiple block transformation method,
6
- # sorry for the method length and the code dup ;)
7
- def self.[](*proc_array)
8
- # Create hash representation, proc_array will still get used sometimes
9
- proc_hash = {}
10
- proc_array.each{ |proc|
11
- proc_hash[proc.name] = proc if proc.respond_to?(:name)
12
- }
13
-
14
- # Build yielder proc
15
- Proc.new{ |*proc_names_and_args|
16
- if proc_names_and_args.empty? # call all procs
17
- ret = proc_array.map(&:call)
18
-
19
- proc_array.size == 1 ? ret.first : ret
20
- else
21
- proc_names, *proc_args = *proc_names_and_args
22
-
23
- if proc_names.is_a? Hash # keys: proc_names, values: args
24
- proc_names.map{ |proc_name, proc_args|
25
- proc = proc_name.is_a?(Integer) ? proc_array[proc_name] : proc_hash[proc_name.to_sym]
26
- proc or raise LocalJumpError, "wrong block name given (#{proc_name})"
27
-
28
- [proc, Array(proc_args)]
29
- }.map{ |proc, proc_args|
30
- proc.call(*proc_args)
31
- }
32
-
33
- else
34
- ret = Array(proc_names).map{ |proc_name|
35
- proc = proc_name.is_a?(Integer) ? proc_array[proc_name] : proc_hash[proc_name.to_sym]
36
- proc or raise LocalJumpError, "wrong block name given (#{proc_name})"
37
-
38
- [proc, Array(proc_args)]
39
- }.map{ |proc, proc_args|
40
- proc.call(*proc_args)
41
- }
3
+ require_relative 'multi_block/version'
4
+ require_relative 'multi_block/implementation'
5
+ require_relative 'multi_block/core_ext'
42
6
 
43
- ret.size == 1 ? ret.first : ret
44
-
45
- end
46
- end
47
- }
48
- end
49
-
50
- # low level mixins
51
- module Object
52
- private
53
-
54
- # to_proc helper, see README
55
- def blocks
56
- MultiBlock#[]
57
- end
58
-
59
- # alias procs blocks
60
- # alias b blocks
61
- end
62
-
63
- ::Object.send :include, ::MultiBlock::Object
64
-
65
- # Bonus array mixin (if you want to)
66
- module Array
67
- # see README for an example
68
- def to_proc
69
- ::MultiBlock[*self]
70
- end
71
- end
72
-
73
- # ::Array.send :include, MultiBlock::Array
74
- end
@@ -0,0 +1,3 @@
1
+ class Array
2
+ include MultiBlock::Array
3
+ end
@@ -0,0 +1,3 @@
1
+ class Object
2
+ include MultiBlock::Object
3
+ end
@@ -0,0 +1,61 @@
1
+ module MultiBlock
2
+ # Multiple block transformation method
3
+ def self.[](*proc_array)
4
+ # Create hash representation, proc_array will still get used sometimes
5
+ proc_hash = {}
6
+ proc_array.each{ |proc|
7
+ proc_hash[proc.name] = proc if proc.respond_to?(:name)
8
+ }
9
+
10
+ # Build yielder proc
11
+ Proc.new{ |*proc_names_and_args|
12
+ if proc_names_and_args.empty? # call all procs
13
+ ret = proc_array.map(&:call)
14
+
15
+ proc_array.size == 1 ? ret.first : ret
16
+ else
17
+ proc_names, *proc_args = *proc_names_and_args
18
+
19
+ if proc_names.is_a? Hash # keys: proc_names, values: args
20
+ proc_names.map{ |proc_name, proc_args|
21
+ proc = proc_name.is_a?(Integer) ? proc_array[proc_name] : proc_hash[proc_name.to_sym]
22
+ proc or raise LocalJumpError, "wrong block name given (#{proc_name})"
23
+
24
+ [proc, Array(proc_args)]
25
+ }.map{ |proc, proc_args|
26
+ proc.call(*proc_args)
27
+ }
28
+
29
+ else
30
+ ret = Array(proc_names).map{ |proc_name|
31
+ proc = proc_name.is_a?(Integer) ? proc_array[proc_name] : proc_hash[proc_name.to_sym]
32
+ proc or raise LocalJumpError, "wrong block name given (#{proc_name})"
33
+
34
+ [proc, Array(proc_args)]
35
+ }.map{ |proc, proc_args|
36
+ proc.call(*proc_args)
37
+ }
38
+
39
+ ret.size == 1 ? ret.first : ret
40
+
41
+ end
42
+ end
43
+ }
44
+ end
45
+
46
+ # Low level mixins
47
+ module Object
48
+ private
49
+
50
+ def blocks
51
+ MultiBlock
52
+ end
53
+ end
54
+
55
+ # Optional Array mixin
56
+ module Array
57
+ def to_proc
58
+ ::MultiBlock[*self]
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,3 @@
1
+ module MultiBlock
2
+ VERSION = "1.1".freeze
3
+ end
@@ -1,19 +1,20 @@
1
1
  # -*- encoding: utf-8 -*-
2
- require 'rubygems' unless defined? Gem
2
+
3
+ require File.expand_path('../lib/multi_block/version', __FILE__)
3
4
 
4
5
  Gem::Specification.new do |s|
5
6
  s.name = "multi_block"
6
- s.version = 1.0
7
+ s.version = MultiBlock::VERSION
7
8
  s.authors = ["Jan Lelis"]
8
9
  s.email = "mail@janlelis.de"
9
- s.homepage = "https://gist.github.com/4b2f5fd0b45118e46d0f"
10
+ s.homepage = "https://github.com/janlelis/multi_block"
10
11
  s.summary = 'MultiBlock is a mini framework for passing multiple blocks to methods.'
11
12
  s.description = 'MultiBlock is a mini framework for passing multiple blocks to methods. It uses "named procs" to accomplish this in a nice way. The receiving method can either yield all blocks, or just call specific ones, identified by order or name. '
12
- s.required_ruby_version = '>= 1.9.2'
13
- s.files = Dir.glob %w{multi_block.gemspec lib/multi_block.rb spec/multi_block_spec.rb}
14
- s.extra_rdoc_files = ["README.rdoc", "LICENSE.txt"]
13
+ s.required_ruby_version = '>= 1.9.3'
14
+ s.files = Dir.glob %w{multi_block.gemspec lib/multi_block.rb lib/multi_block/version.rb lib/multi_block/implementation.rb lib/multi_block/core_ext.rb lib/multi_block/array.rb spec/multi_block_spec.rb}
15
+ s.extra_rdoc_files = ["README.rdoc", "MIT-LICENSE.txt", "CHANGELOG.rdoc", ".travis.yml"]
15
16
  s.license = 'MIT'
16
- s.add_dependency 'named_proc'
17
- s.add_development_dependency 'rspec'
18
- s.add_development_dependency 'rspec-core'
17
+ s.add_dependency 'named_proc', '~> 1.1'
18
+ s.add_development_dependency 'rspec', '~> 3.2'
19
+ s.add_development_dependency 'rake', '~> 10.4'
19
20
  end
@@ -1,83 +1,109 @@
1
1
  # encoding: utf-8
2
2
  require_relative '../lib/multi_block'
3
3
 
4
- describe "blocks" do
4
+ describe "Object#blocks" do
5
5
  it "returns the MutliBlock constant (for calling [] on it)" do
6
- blocks.should == MultiBlock
6
+ expect( blocks ).to be MultiBlock
7
7
  end
8
8
  end
9
9
 
10
- describe MultiBlock, "#[]" do
11
- it "yield without args: calls every block and returns array of results" do
12
- def null
13
- yield
14
- end
15
-
16
- null(&blocks[
17
- proc{5},
18
- proc{6},
19
- ]).should == [5,6]
20
- end
10
+ describe "MultiBlock#[]" do
11
+ describe "yield without arguments" do
12
+ it "calls every block and returns array of results" do
13
+ def null
14
+ yield
15
+ end
21
16
 
22
- it "yield with symbol: calls the specified proc, other args get passed" do
23
- def symbol
24
- yield :success, "Code Brawl!"
17
+ expect( null(&blocks[
18
+ proc{5},
19
+ proc{6},
20
+ ]) ).to eq [5,6]
25
21
  end
26
-
27
- symbol(&blocks[
28
- proc{5},
29
- proc.success{|e| e.swapcase},
30
- proc.error{6},
31
- ]).should == "cODE bRAWL!"
32
22
  end
33
-
34
- it 'yield with symbol: raises LocalJumpError if proc name is wrong' do
35
- def wrong_name
36
- yield :wrong, "Code Brawl!"
37
- end
23
+
24
+ describe "yield with symbol" do
25
+ it "calls the specified proc, other args get passed" do
26
+ def symbol
27
+ yield :success, "Code Brawl!"
28
+ end
38
29
 
39
- proc do
40
- wrong_name(&blocks[
30
+ expect( symbol(&blocks[
41
31
  proc{5},
42
32
  proc.success{|e| e.swapcase},
43
33
  proc.error{6},
44
- ])
45
- end.should raise_exception(LocalJumpError)
46
- end
34
+ ]) ).to eq "cODE bRAWL!"
35
+ end
47
36
 
48
- it "yield with integer: calls the n-th proc, other args get passed" do
49
- def integer
50
- yield 2
37
+ it 'will raise LocalJumpError if proc name is wrong' do
38
+ def wrong_name
39
+ yield :wrong, "Code Brawl!"
40
+ end
41
+
42
+ expect{
43
+ wrong_name(&blocks[
44
+ proc{5},
45
+ proc.success{|e| e.swapcase},
46
+ proc.error{6},
47
+ ])
48
+ }.to raise_exception(LocalJumpError)
51
49
  end
50
+ end
51
+
52
+ describe "yield with integer" do
53
+ it "calls the n-th proc, other args get passed" do
54
+ def integer
55
+ yield 2
56
+ end
52
57
 
53
- integer(&blocks[
54
- proc{5},
55
- proc.success{|e| e.swapcase},
56
- proc.error{6},
57
- ]).should == 6
58
+ expect( integer(&blocks[
59
+ proc{5},
60
+ proc.success{|e| e.swapcase},
61
+ proc.error{6},
62
+ ]) ).to eq 6
63
+ end
58
64
  end
59
-
60
- it "yield with array: calls all procs, indentified by symbol or integer, other args get passed" do
61
- def array
62
- yield [:success, :error], "Code Brawl!"
65
+
66
+ describe "yield with array" do
67
+ it "calls all procs, indentified by symbol or integer, other args get passed" do
68
+ def array
69
+ yield [:success, :error], "Code Brawl!"
70
+ end
71
+
72
+ expect( array(&blocks[
73
+ proc{5},
74
+ proc.success{|e| e.swapcase},
75
+ proc.error{|e| e.downcase},
76
+ ]) ).to eq ["cODE bRAWL!", "code brawl!"]
63
77
  end
78
+ end
79
+
80
+ describe "yield with hash" do
81
+ it "takes keys as proc names and passes values as proc args" do
82
+ def hash
83
+ yield success: "Code Brawl!", error: [500, "Internal Brawl Error"]
84
+ end
64
85
 
65
- array(&blocks[
66
- proc{5},
67
- proc.success{|e| e.swapcase},
68
- proc.error{|e| e.downcase},
69
- ]).should == ["cODE bRAWL!", "code brawl!"]
86
+ expect( hash(&blocks[
87
+ proc{5},
88
+ proc.success{|e| e.swapcase},
89
+ proc.error{|no, msg| "Error #{no}: #{msg}"},
90
+ ]).sort ).to eq ["Error 500: Internal Brawl Error", "cODE bRAWL!"]
91
+ end
70
92
  end
71
-
72
- it "yield with hash: takes keys as proc names and passes values as proc args" do
73
- def hash
74
- yield success: "Code Brawl!", error: [500, "Internal Brawl Error"]
93
+ end
94
+
95
+ describe "Array#to_proc" do
96
+ it "works without blocks helper" do
97
+ def another_method
98
+ yield
75
99
  end
76
-
77
- hash(&blocks[
100
+
101
+ proc_array = [
78
102
  proc{5},
79
- proc.success{|e| e.swapcase},
80
- proc.error{|no, msg| "Error #{no}: #{msg}"},
81
- ]).sort.should == ["Error 500: Internal Brawl Error", "cODE bRAWL!"]
103
+ proc{6},
104
+ ]
105
+ proc_array.send :extend, MultiBlock::Array
106
+
107
+ expect( another_method(&proc_array) ).to eq [5,6]
82
108
  end
83
109
  end
metadata CHANGED
@@ -1,50 +1,58 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: multi_block
3
3
  version: !ruby/object:Gem::Version
4
- version: '1.0'
5
- prerelease:
4
+ version: '1.1'
6
5
  platform: ruby
7
6
  authors:
8
7
  - Jan Lelis
9
8
  autorequire:
10
9
  bindir: bin
11
10
  cert_chain: []
12
- date: 2011-10-24 00:00:00.000000000Z
11
+ date: 2015-03-20 00:00:00.000000000 Z
13
12
  dependencies:
14
13
  - !ruby/object:Gem::Dependency
15
14
  name: named_proc
16
- requirement: &13586400 !ruby/object:Gem::Requirement
17
- none: false
15
+ requirement: !ruby/object:Gem::Requirement
18
16
  requirements:
19
- - - ! '>='
17
+ - - "~>"
20
18
  - !ruby/object:Gem::Version
21
- version: '0'
19
+ version: '1.1'
22
20
  type: :runtime
23
21
  prerelease: false
24
- version_requirements: *13586400
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.1'
25
27
  - !ruby/object:Gem::Dependency
26
28
  name: rspec
27
- requirement: &13583220 !ruby/object:Gem::Requirement
28
- none: false
29
+ requirement: !ruby/object:Gem::Requirement
29
30
  requirements:
30
- - - ! '>='
31
+ - - "~>"
31
32
  - !ruby/object:Gem::Version
32
- version: '0'
33
+ version: '3.2'
33
34
  type: :development
34
35
  prerelease: false
35
- version_requirements: *13583220
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '3.2'
36
41
  - !ruby/object:Gem::Dependency
37
- name: rspec-core
38
- requirement: &13582300 !ruby/object:Gem::Requirement
39
- none: false
42
+ name: rake
43
+ requirement: !ruby/object:Gem::Requirement
40
44
  requirements:
41
- - - ! '>='
45
+ - - "~>"
42
46
  - !ruby/object:Gem::Version
43
- version: '0'
47
+ version: '10.4'
44
48
  type: :development
45
49
  prerelease: false
46
- version_requirements: *13582300
47
- description: ! 'MultiBlock is a mini framework for passing multiple blocks to methods.
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '10.4'
55
+ description: 'MultiBlock is a mini framework for passing multiple blocks to methods.
48
56
  It uses "named procs" to accomplish this in a nice way. The receiving method can
49
57
  either yield all blocks, or just call specific ones, identified by order or name. '
50
58
  email: mail@janlelis.de
@@ -52,36 +60,43 @@ executables: []
52
60
  extensions: []
53
61
  extra_rdoc_files:
54
62
  - README.rdoc
55
- - LICENSE.txt
63
+ - MIT-LICENSE.txt
64
+ - CHANGELOG.rdoc
65
+ - ".travis.yml"
56
66
  files:
57
- - multi_block.gemspec
67
+ - ".travis.yml"
68
+ - CHANGELOG.rdoc
69
+ - MIT-LICENSE.txt
70
+ - README.rdoc
58
71
  - lib/multi_block.rb
72
+ - lib/multi_block/array.rb
73
+ - lib/multi_block/core_ext.rb
74
+ - lib/multi_block/implementation.rb
75
+ - lib/multi_block/version.rb
76
+ - multi_block.gemspec
59
77
  - spec/multi_block_spec.rb
60
- - README.rdoc
61
- - LICENSE.txt
62
- homepage: https://gist.github.com/4b2f5fd0b45118e46d0f
78
+ homepage: https://github.com/janlelis/multi_block
63
79
  licenses:
64
80
  - MIT
81
+ metadata: {}
65
82
  post_install_message:
66
83
  rdoc_options: []
67
84
  require_paths:
68
85
  - lib
69
86
  required_ruby_version: !ruby/object:Gem::Requirement
70
- none: false
71
87
  requirements:
72
- - - ! '>='
88
+ - - ">="
73
89
  - !ruby/object:Gem::Version
74
- version: 1.9.2
90
+ version: 1.9.3
75
91
  required_rubygems_version: !ruby/object:Gem::Requirement
76
- none: false
77
92
  requirements:
78
- - - ! '>='
93
+ - - ">="
79
94
  - !ruby/object:Gem::Version
80
95
  version: '0'
81
96
  requirements: []
82
97
  rubyforge_project:
83
- rubygems_version: 1.8.11
98
+ rubygems_version: 2.4.6
84
99
  signing_key:
85
- specification_version: 3
100
+ specification_version: 4
86
101
  summary: MultiBlock is a mini framework for passing multiple blocks to methods.
87
102
  test_files: []