decorator 0.0.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/.gemtest ADDED
File without changes
data/History.txt ADDED
@@ -0,0 +1,3 @@
1
+ === 2012/2/24
2
+
3
+ * gem 化
data/Manifest.txt ADDED
@@ -0,0 +1,8 @@
1
+ lib/decorator.rb
2
+ lib/decorator/only.rb
3
+ lib/decorator/decorator.rb
4
+ lib/decorator/kwargsable.rb
5
+ README.rdoc
6
+ Rakefile
7
+ History.txt
8
+ Manifest.txt
data/README.rdoc ADDED
@@ -0,0 +1,50 @@
1
+ == Decorator
2
+ * http://github.com/pasberth/Decorator
3
+
4
+
5
+ == DESCRIPTION:
6
+ the Decorator make a decorator like Python.
7
+
8
+ == Usage
9
+
10
+ require 'decorator'
11
+
12
+ または
13
+
14
+ require 'decorator/only'
15
+
16
+ require 'decorator' だと Module#decorator だけでなく Module#kwargsable も一緒に使えます。
17
+ require 'decorator/only' だと Module#decorator だけがロードされます
18
+
19
+ 普通、このモジュールで使う関数はModule#decoratorのみです。
20
+ それはデコレータを作成するデコレータです。デコレータを作る場合は通常これをデコレータとします。
21
+ *example*:
22
+ class Module
23
+ decorator
24
+ def wrap func, *args, &blk
25
+ puts "wrapped!"
26
+ proc { func.call *args, &blk }
27
+
28
+ デコレータの第一引数は必ずMethodです。
29
+ この場合のwrapはデコレータとして使用できます。
30
+
31
+ class TestClass
32
+ wrap
33
+ def wrapped *args, &blk
34
+ puts "IN!"
35
+
36
+ もしデコレータに引数を渡した場合、それはすべてデコレータに一緒に渡されます。
37
+
38
+ class TestClass
39
+ wrap(*example_args)
40
+ def wrapped *args, &blk
41
+ puts "IN!"
42
+
43
+ => ↓のargsにexample_argsが渡される
44
+
45
+ def wrap func, *args, &blk
46
+ puts "wrapped!"
47
+ proc { func.call *args, &blk }
48
+
49
+ デコレータの戻り値がProcである場合、関数はそのProcに置き換えられます。
50
+ たとえばこの場合、wrappedはwrap内のprocに置き換えられます。
data/Rakefile ADDED
@@ -0,0 +1,9 @@
1
+ require './lib/decorator'
2
+ require 'hoe'
3
+
4
+ Hoe.spec 'decorator' do
5
+ self.developer 'pasberth', 'pasberth@gmail.com'
6
+ self.rubyforge_name = self.name
7
+ self.readme_file = 'README.rdoc'
8
+ self.version = Decorator::VERSION
9
+ end
data/lib/decorator.rb ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env ruby
2
+ # -*- coding: utf-8 -*-
3
+
4
+ $:.unshift(File.dirname(__FILE__)) unless
5
+ $:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))
6
+
7
+ require "decorator/only"
8
+ require "decorator/kwargsable"
@@ -0,0 +1,140 @@
1
+ #!/usr/bin/env ruby
2
+ # -*- coding: utf-8 -*-
3
+
4
+ module Decorator
5
+ VERSION = "0.0.1"
6
+ end
7
+
8
+ class Object
9
+
10
+ private
11
+
12
+ def decorators
13
+ @decorators ||= []
14
+ end
15
+
16
+ def add_decorator _f, *args, &blk
17
+ _f = case _f
18
+ when UnboundMethod then _f.bind self
19
+ when Method then _f
20
+ end
21
+ _after = ->(_func, *_args, &_blk) do # the _after is called when created the a_function
22
+ # selfがこのクラスまたはモジュールのインスタンスになるようにinstance_execなどをすること
23
+ # define_methodなどでもselfは正しくなるのでそれでok
24
+ _new_method = ->(*__args, &__blk) do # new function replaced to the a_function
25
+ _func = case _func
26
+ when UnboundMethod then _func.bind self
27
+ when Method then _func
28
+ end
29
+ res = _f.call _func, *args, &blk
30
+ if res.respond_to? :to_proc
31
+ define_singleton_method _func.name, &res
32
+ send _func.name, *__args, &__blk
33
+ elsif Method === res || UnboundMethod === res
34
+ define_singleton_method _func.name, res
35
+ send _func.name, *__args, &__blk
36
+ end
37
+ end
38
+ return _new_method
39
+ end
40
+ decorators << [_after, args, blk]
41
+ true
42
+ end
43
+
44
+ alias decoratable_original_singleton_method_added singleton_method_added
45
+
46
+ def singleton_method_added funcname
47
+ decoratable_original_singleton_method_added(funcname).tap do
48
+ next if decorators.empty?
49
+ origin = method funcname
50
+ func = origin
51
+
52
+ until decorators.empty?
53
+ decorators.pop.tap do |f, args, blk|
54
+ res = f.call func, *args, &blk
55
+ if res.respond_to? :to_proc
56
+ define_singleton_method funcname, &res
57
+ func = method func.name
58
+ elsif Method === res || UnboundMethod === res
59
+ define_singleton_method funcname, res
60
+ func = method func.name
61
+ end
62
+ end
63
+ end
64
+ end
65
+ end
66
+ end
67
+
68
+
69
+ class Module
70
+ # デコレータを作成するデコレータです。デコレータを作る場合は通常これをデコレータとします。
71
+ # example:
72
+ # class Module
73
+ # decorator
74
+ # def wrap func, *args, &blk
75
+ # puts "wrapped!"
76
+ # proc { func.call *args, &blk }
77
+ # デコレータの第一引数は必ずMethodです。
78
+ # この場合のwrapはデコレータとして使用できます。
79
+ # class TestClass
80
+ # wrap
81
+ # def wrapped *args, &blk
82
+ # puts "IN!"
83
+ # もしデコレータに引数を渡した場合、それはすべてデコレータに一緒に渡されます。
84
+ # class TestClass
85
+ # wrap(*example_args)
86
+ # def wrapped *args, &blk
87
+ # puts "IN!"
88
+ # => ↓のargsにexample_argsが渡される
89
+ # def wrap func, *args, &blk
90
+ # puts "wrapped!"
91
+ # proc { func.call *args, &blk }
92
+ # デコレータの戻り値がProcである場合、関数はそのProcに置き換えられます。
93
+ # たとえばこの場合、wrappedはwrap内のprocに置き換えられます。
94
+ def decorator *args, &blk
95
+
96
+ # for example,
97
+ # class Example
98
+ # decorator
99
+ # def self.logging
100
+ # ...
101
+ #
102
+ # logging
103
+ # def a_function
104
+ # ...
105
+ after = ->(_f, *_a, &_b) do # the after is called when created the self.logging
106
+ new_method = ->(*args, &blk) do # new function replaced to the self.logging
107
+ add_decorator _f, *args, &blk
108
+ end
109
+
110
+ return new_method
111
+ end
112
+
113
+ decorators << [after, args, blk]
114
+ true
115
+ end
116
+
117
+
118
+ alias decoratable_original_method_added method_added
119
+
120
+ def method_added funcname
121
+ decoratable_original_method_added(funcname).tap do
122
+ next if decorators.empty?
123
+ origin = instance_method funcname
124
+ func = origin
125
+
126
+ until decorators.empty?
127
+ decorators.pop.tap do |f, args, blk|
128
+ res = f.call func, *args, &blk
129
+ if res.respond_to? :to_proc
130
+ define_method funcname, &res
131
+ func = instance_method func.name
132
+ elsif Method === res || UnboundMethod === res
133
+ define_method funcname, res
134
+ func = instance_method func.name
135
+ end
136
+ end
137
+ end
138
+ end
139
+ end
140
+ end
@@ -0,0 +1,41 @@
1
+ #!/usr/bin/env ruby
2
+ # -*- coding: utf-8 -*-
3
+
4
+ require 'decorator/only'
5
+
6
+ class Module
7
+
8
+ decorator
9
+ def kwargsable func, default_args={}, &default_blk
10
+ params = func.parameters
11
+ params_nonblock = params.reject { |i| i[0] == :block }
12
+ xs = params_nonblock.map { |i| i[1] }
13
+ ->(*args, &blk) do
14
+
15
+ if args.last.respond_to? :to_hash
16
+ kwargs = args.pop.to_hash
17
+ else
18
+ kwargs = {}
19
+ end
20
+
21
+ args.fill nil, args.length, params_nonblock.length - args.length - 1
22
+
23
+ default_args.each do |key, default|
24
+ next unless xs.include? key
25
+ i = xs.index(key)
26
+ if args[i].nil? then args[i] = default
27
+ end
28
+ end
29
+
30
+ blk = default_blk if blk.nil?
31
+
32
+ kwargs.each do |key, arg|
33
+ next unless xs.include? key
34
+ kwargs.delete key
35
+ args[xs.index(key)] = arg
36
+ end
37
+
38
+ func.call *args, kwargs, &blk
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env ruby
2
+ # -*- coding: utf-8 -*-
3
+
4
+ $:.unshift(File.dirname File.dirname(__FILE__)) unless
5
+ $:.include?(File.dirname File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname File.dirname(__FILE__)))
6
+
7
+ require "decorator/decorator"
metadata ADDED
@@ -0,0 +1,80 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: decorator
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - pasberth
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-02-24 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: rdoc
16
+ requirement: &70276038777500 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: '3.10'
22
+ type: :development
23
+ prerelease: false
24
+ version_requirements: *70276038777500
25
+ - !ruby/object:Gem::Dependency
26
+ name: hoe
27
+ requirement: &70276038777080 !ruby/object:Gem::Requirement
28
+ none: false
29
+ requirements:
30
+ - - ~>
31
+ - !ruby/object:Gem::Version
32
+ version: '2.13'
33
+ type: :development
34
+ prerelease: false
35
+ version_requirements: *70276038777080
36
+ description: the Decorator make a decorator like Python.
37
+ email:
38
+ - pasberth@gmail.com
39
+ executables: []
40
+ extensions: []
41
+ extra_rdoc_files:
42
+ - History.txt
43
+ - Manifest.txt
44
+ files:
45
+ - lib/decorator.rb
46
+ - lib/decorator/only.rb
47
+ - lib/decorator/decorator.rb
48
+ - lib/decorator/kwargsable.rb
49
+ - README.rdoc
50
+ - Rakefile
51
+ - History.txt
52
+ - Manifest.txt
53
+ - .gemtest
54
+ homepage: http://github.com/pasberth/Decorator
55
+ licenses: []
56
+ post_install_message:
57
+ rdoc_options:
58
+ - --main
59
+ - README.rdoc
60
+ require_paths:
61
+ - lib
62
+ required_ruby_version: !ruby/object:Gem::Requirement
63
+ none: false
64
+ requirements:
65
+ - - ! '>='
66
+ - !ruby/object:Gem::Version
67
+ version: '0'
68
+ required_rubygems_version: !ruby/object:Gem::Requirement
69
+ none: false
70
+ requirements:
71
+ - - ! '>='
72
+ - !ruby/object:Gem::Version
73
+ version: '0'
74
+ requirements: []
75
+ rubyforge_project: decorator
76
+ rubygems_version: 1.8.10
77
+ signing_key:
78
+ specification_version: 3
79
+ summary: the Decorator make a decorator like Python.
80
+ test_files: []