forwardablex 0.1.0

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/.gitignore ADDED
@@ -0,0 +1,18 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
18
+ html
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in forwardablex.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 Keita Yamaguchi
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,68 @@
1
+ # forwardablex
2
+
3
+ forwardablex is a ruby library to extend forwardable.rb.
4
+
5
+ ## Installation
6
+
7
+ gem install forwardablex
8
+
9
+ ## Usage
10
+
11
+ ### Forward to Instance Variable
12
+
13
+ ```ruby
14
+ Receiver = Struct(:m)
15
+ class Forwarder
16
+ forward :@receiver, :m
17
+ def initialize
18
+ @recevier = Receiver.new("forwarded")
19
+ end
20
+ end
21
+ Forwarder.new.m #=> "forwarded"
22
+ ```
23
+
24
+ ### Forward to Proc Receiver
25
+
26
+ ```ruby
27
+ class Forwarder
28
+ forward lambda{Struct(:m).new("forwarded")}, :m
29
+ end
30
+ Forwarder.new.m #=> "forwarded"
31
+ ```
32
+
33
+ ### Forward to Instance
34
+
35
+ ```ruby
36
+ Receiver = Struct(:m)
37
+ class Forwarder
38
+ forward Receiver.new("forwarded"), :m
39
+ end
40
+ Forwarder.new.m #=> "forwarded"
41
+ ```
42
+
43
+ ### Class Method Accessor
44
+
45
+ ```ruby
46
+ Receiver = Struct(:name)
47
+ class Forwarder
48
+ class << self
49
+ def m
50
+ "forwarded"
51
+ end
52
+ end
53
+ forward self, :m
54
+ end
55
+ Forwarder.new.m #=> "forwarded"
56
+ ```
57
+
58
+ ## Licence
59
+
60
+ forwardablex is free software distributed under MIT licence.
61
+
62
+ ## Contributing
63
+
64
+ 1. Fork it
65
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
66
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
67
+ 4. Push to the branch (`git push origin my-new-feature`)
68
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,16 @@
1
+ require "bundler/gem_tasks"
2
+
3
+ desc 'Test specs'
4
+ task 'test' do
5
+ sh "bundle exec bacon -a"
6
+ end
7
+
8
+ desc 'Generate API document'
9
+ task 'html' do
10
+ sh "bundle exec yard doc -o html --hide-void-return --no-api"
11
+ end
12
+
13
+ desc 'Show undocumented function list'
14
+ task 'html:undoc' do
15
+ sh "bundle exec yard stats --list-undoc --no-api --compact"
16
+ end
@@ -0,0 +1,23 @@
1
+ # -*- ruby -*-
2
+ # -*- encoding: utf-8 -*-
3
+ lib = File.expand_path('../lib', __FILE__)
4
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
5
+ require 'forwardablex/version'
6
+
7
+ Gem::Specification.new do |gem|
8
+ gem.name = "forwardablex"
9
+ gem.version = ForwardableX::VERSION
10
+ gem.authors = ["Keita Yamaguchi"]
11
+ gem.email = ["keita.yamaguchi@gmail.com"]
12
+ gem.description = "This is a library to extend Forwardable functions"
13
+ gem.summary = "Forwardable extension"
14
+ gem.homepage = "https://github.com/keita/forwardablex"
15
+
16
+ gem.files = `git ls-files`.split($/)
17
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
18
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
19
+ gem.require_paths = ["lib"]
20
+ gem.add_development_dependency "bacon"
21
+ gem.add_development_dependency "yard", "~> 0.8.5"
22
+ gem.add_development_dependency "redcarpet"
23
+ end
@@ -0,0 +1,110 @@
1
+ # Copyright (C) 2013 Keita Yamaguchi <keita.yamaguchi@gmail.com>
2
+
3
+ require "forwardablex/version"
4
+
5
+ # ForwardableX is a module for providing extra Forwardable functions. Benefits
6
+ # to use this library are the following:
7
+ #
8
+ # - you can use easy keyword "forward", instead of "def_instance_delegator" or "def_delegator"
9
+ # - you can specify message receiver as instance variable name, Proc object or plain object
10
+ # - no need to declare "extend Forwardable"
11
+ # - forwardable.rb compatible API
12
+ #
13
+ # @example Forward to Instance Variable
14
+ # Receiver = Struct(:m)
15
+ # class Forwarder
16
+ # forward :@receiver, :m
17
+ # def initialize
18
+ # @recevier = Receiver.new("forwarded")
19
+ # end
20
+ # end
21
+ # Forwarder.new.m #=> "forwarded"
22
+ # @example Forward to Proc Receiver
23
+ # class Forwarder
24
+ # forward lambda{Struct(:m).new("forwarded")}, :m
25
+ # end
26
+ # Forwarder.new.m #=> "forwarded"
27
+ # @example Forward to Instance
28
+ # Receiver = Struct(:m)
29
+ # class Forwarder
30
+ # forward Receiver.new("forwarded"), :m
31
+ # end
32
+ # Forwarder.new.m #=> "forwarded"
33
+ # @example Class Method Accessor
34
+ # Receiver = Struct(:name)
35
+ # class Forwarder
36
+ # class << self
37
+ # def m
38
+ # "forwarded"
39
+ # end
40
+ # end
41
+ # forward self, :m
42
+ # end
43
+ # Forwarder.new.m #=> "forwarded"
44
+ module ForwardableX
45
+ # Define a method that forwards the message to the receiver. You can specify
46
+ # receiver as instance variable name, Proc object, and plain object.
47
+ #
48
+ # @param receiver [Symbol, String, Proc, or Object]
49
+ # message receiver
50
+ # @param method [Symbol]
51
+ # method name that we forward to
52
+ # @param name [Symbol]
53
+ # method name that we forward from
54
+ # @return [void]
55
+ def forward(receiver, method, name=method)
56
+ context = self.kind_of?(Module) ? self : self.singleton_class
57
+ context.instance_eval do
58
+ case receiver
59
+ when Symbol, String
60
+ define_method(name) do |*args, &b|
61
+ instance_variable_get(receiver).__send__(method, *args, &b)
62
+ end
63
+ when Proc
64
+ define_method(name) do |*args, &b|
65
+ receiver.call.__send__(method, *args, &b)
66
+ end
67
+ else
68
+ define_method(name) do |*args, &b|
69
+ receiver.__send__(method, *args, &b)
70
+ end
71
+ end
72
+ end
73
+ end
74
+ alias :def_instance_delegator :forward
75
+ alias :def_singleton_delegator :forward
76
+ alias :def_delegator :forward
77
+
78
+ # Define each method that calls the receiver's method.
79
+ #
80
+ # @param receiver [Symbol, String, Proc, or Object]
81
+ # message receiver
82
+ # @param methods [Array<Symbol>]
83
+ # method names that we forward to
84
+ # @return [void]
85
+ def forward!(receiver, *methods)
86
+ methods.delete("__send__")
87
+ methods.delete("__id__")
88
+ methods.each {|method| forward(receiver, method)}
89
+ end
90
+ alias :def_instance_delegators :forward!
91
+ alias :def_singleton_delegators :forward!
92
+ alias :def_delegators :forward!
93
+
94
+ # Same as Forwardable#delegate, but you can specify receivers as instance
95
+ # variable name, Proc object, and plain object.
96
+ #
97
+ # @param hash [Hash]
98
+ # the hash table contains keys as methods and values as recevier
99
+ # @return [void]
100
+ def delegate(hash)
101
+ hash.each do |methods, receiver|
102
+ forward!(receiver, *methods)
103
+ end
104
+ end
105
+ end
106
+
107
+ # @api private
108
+ class Object
109
+ extend ForwardableX
110
+ end
@@ -0,0 +1,4 @@
1
+ module ForwardableX
2
+ # version of ForwardableX
3
+ VERSION = "0.1.0"
4
+ end
@@ -0,0 +1,118 @@
1
+ require 'forwardable'
2
+ require 'forwardablex'
3
+
4
+ class Receiver
5
+ def method_missing(name, *args)
6
+ name
7
+ end
8
+ end
9
+
10
+ class Forwarder
11
+ attr_reader :name
12
+
13
+ def initialize(name=self.class)
14
+ @rec = Receiver.new
15
+ @name = name
16
+ end
17
+ end
18
+
19
+ class XForwarder < Forwarder
20
+ forward :@rec, :m1
21
+ forward :@rec, :m1, :mm1
22
+ forward! :@rec, :m2, :m3
23
+ forward Proc.new{Receiver.new}, :m4
24
+ forward Proc.new{Receiver.new}, :m4, :mm4
25
+ forward! Proc.new{Receiver.new}, :m5, :m6
26
+ forward Receiver.new, :m7
27
+ forward Receiver.new, :m7, :mm7
28
+ forward! Receiver.new, :m8, :m9
29
+ end
30
+
31
+ class DefDelegatorForwarder < Forwarder
32
+ def_delegator :@rec, :m1
33
+ def_delegator :@rec, :m1, :mm1
34
+ def_delegators :@rec, :m2, :m3
35
+ def_delegator Proc.new{Receiver.new}, :m4
36
+ def_delegator Proc.new{Receiver.new}, :m4, :mm4
37
+ def_delegators Proc.new{Receiver.new}, :m5, :m6
38
+ def_delegator Receiver.new, :m7
39
+ def_delegator Receiver.new, :m7, :mm7
40
+ def_delegators Receiver.new, :m8, :m9
41
+ end
42
+
43
+ class DefInstanceDelegatorForwarder < Forwarder
44
+ def_instance_delegator :@rec, :m1
45
+ def_instance_delegator :@rec, :m1, :mm1
46
+ def_instance_delegators :@rec, :m2, :m3
47
+ def_instance_delegator Proc.new{Receiver.new}, :m4
48
+ def_instance_delegator Proc.new{Receiver.new}, :m4, :mm4
49
+ def_instance_delegators Proc.new{Receiver.new}, :m5, :m6
50
+ def_instance_delegator Receiver.new, :m7
51
+ def_instance_delegator Receiver.new, :m7, :mm7
52
+ def_instance_delegators Receiver.new, :m8, :m9
53
+ end
54
+
55
+ class DelegateForwarder < Forwarder
56
+ delegate :m1 => :@rec
57
+ delegate [:m2, :m3] => :@rec
58
+ delegate :m4 => Proc.new{Receiver.new}
59
+ delegate [:m5, :m6] => Proc.new{Receiver.new}
60
+ delegate :m7 => Receiver.new
61
+ delegate [:m8, :m9] => Receiver.new
62
+ end
63
+
64
+ xforwarder = Forwarder.new("xforwarder").tap do |obj|
65
+ obj.extend ForwardableX
66
+ obj.forward :@rec, :m1
67
+ obj.forward :@rec, :m1, :mm1
68
+ obj.forward! :@rec, :m2, :m3
69
+ obj.forward Proc.new{Receiver.new}, :m4
70
+ obj.forward Proc.new{Receiver.new}, :m4, :mm4
71
+ obj.forward! Proc.new{Receiver.new}, :m5, :m6
72
+ obj.forward Receiver.new, :m7
73
+ obj.forward Receiver.new, :m7, :mm7
74
+ obj.forward! Receiver.new, :m8, :m9
75
+ end
76
+
77
+ singletonforwarder = Forwarder.new("singletonforwarder").tap do |obj|
78
+ obj.extend ForwardableX
79
+ obj.def_singleton_delegator :@rec, :m1
80
+ obj.def_singleton_delegator :@rec, :m1, :mm1
81
+ obj.def_singleton_delegators :@rec, :m2, :m3
82
+ obj.def_singleton_delegator Proc.new{Receiver.new}, :m4
83
+ obj.def_singleton_delegator Proc.new{Receiver.new}, :m4, :mm4
84
+ obj.def_singleton_delegators Proc.new{Receiver.new}, :m5, :m6
85
+ obj.def_singleton_delegator Receiver.new, :m7
86
+ obj.def_singleton_delegator Receiver.new, :m7, :mm7
87
+ obj.def_singleton_delegators Receiver.new, :m8, :m9
88
+ end
89
+
90
+ describe 'ForwardableX' do
91
+ [ XForwarder.new,
92
+ DefDelegatorForwarder.new,
93
+ DefInstanceDelegatorForwarder.new,
94
+ DelegateForwarder.new,
95
+ xforwarder,
96
+ singletonforwarder
97
+ ].each do |obj|
98
+ describe obj.name do
99
+ it 'should forward' do
100
+ obj.m1.should == :m1
101
+ obj.m2.should == :m2
102
+ obj.m3.should == :m3
103
+ obj.m4.should == :m4
104
+ obj.m5.should == :m5
105
+ obj.m6.should == :m6
106
+ obj.m7.should == :m7
107
+ obj.m8.should == :m8
108
+ obj.m9.should == :m9
109
+ end
110
+
111
+ unless obj.kind_of? DelegateForwarder
112
+ it 'should forward by alias' do
113
+ obj.mm1.should == :m1
114
+ end
115
+ end
116
+ end
117
+ end
118
+ end
metadata ADDED
@@ -0,0 +1,104 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: forwardablex
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Keita Yamaguchi
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-04-03 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: bacon
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :development
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '0'
30
+ - !ruby/object:Gem::Dependency
31
+ name: yard
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ~>
36
+ - !ruby/object:Gem::Version
37
+ version: 0.8.5
38
+ type: :development
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ~>
44
+ - !ruby/object:Gem::Version
45
+ version: 0.8.5
46
+ - !ruby/object:Gem::Dependency
47
+ name: redcarpet
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ! '>='
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ type: :development
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ description: This is a library to extend Forwardable functions
63
+ email:
64
+ - keita.yamaguchi@gmail.com
65
+ executables: []
66
+ extensions: []
67
+ extra_rdoc_files: []
68
+ files:
69
+ - .gitignore
70
+ - Gemfile
71
+ - LICENSE.txt
72
+ - README.md
73
+ - Rakefile
74
+ - forwardablex.gemspec
75
+ - lib/forwardablex.rb
76
+ - lib/forwardablex/version.rb
77
+ - test/spec_forwardablex.rb
78
+ homepage: https://github.com/keita/forwardablex
79
+ licenses: []
80
+ post_install_message:
81
+ rdoc_options: []
82
+ require_paths:
83
+ - lib
84
+ required_ruby_version: !ruby/object:Gem::Requirement
85
+ none: false
86
+ requirements:
87
+ - - ! '>='
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ required_rubygems_version: !ruby/object:Gem::Requirement
91
+ none: false
92
+ requirements:
93
+ - - ! '>='
94
+ - !ruby/object:Gem::Version
95
+ version: '0'
96
+ requirements: []
97
+ rubyforge_project:
98
+ rubygems_version: 1.8.24
99
+ signing_key:
100
+ specification_version: 3
101
+ summary: Forwardable extension
102
+ test_files:
103
+ - test/spec_forwardablex.rb
104
+ has_rdoc: