multi_block 1.0 → 1.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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: []